C# has evolved significantly over the years, introducing modern features that make programming more concise, readable, and efficient. One of these features is record types in C#. Introduced in C# 9.0, records allow developers to create immutable objects, simplifying data modeling and value-based equality. In this article, we will explore everything you need to know about C# records, their syntax, practical examples, and real-world use cases.
Record types are reference types (and optionally structs) in C# designed to hold immutable data. Unlike classes, which focus on behavior, records are primarily used for storing data with value-based equality.
Records provide several benefits compared to regular classes:
| Feature | Class | Record |
|---|---|---|
| Immutability | No, unless manually implemented | Yes, built-in support |
| Value-based Equality | No, compares references by default | Yes, compares property values |
| Concise Syntax | Requires manual property definitions | Supports primary constructors |
Here is the simplest example of a C# record:
public record Person(string FirstName, string LastName, int Age);
var person1 = new Person("Alice", "Johnson", 30); var person2 = new Person("Alice", "Johnson", 30); Console.WriteLine(person1); // Output: Person { FirstName = Alice, LastName = Johnson, Age = 30 } Console.WriteLine(person1 == person2); // Output: True (value-based equality)
Many developers wonder whether to use a record or a class. Here's a quick guide:
public class EmployeeClass { public string Name { get; set; } public int Id { get; set; } } public record EmployeeRecord(string Name, int Id); var empClass1 = new EmployeeClass { Name = "John", Id = 1 }; var empClass2 = new EmployeeClass { Name = "John", Id = 1 }; Console.WriteLine(empClass1 == empClass2); // False var empRecord1 = new EmployeeRecord("John", 1); var empRecord2 = new EmployeeRecord("John", 1); Console.WriteLine(empRecord1 == empRecord2); // True
When working with C#, developers often face a choice between using a class or a record to model data. While both are reference types, they serve different purposes and are optimized for different scenarios.
| Feature | Class | Record |
|---|---|---|
| Purpose | Focus on behavior and functionality | Focus on immutable data and value-based equality |
| Equality | Reference-based by default | Value-based (compares property values automatically) |
| Immutability | Optional; requires manual implementation | Built-in support; properties are read-only by default |
| Syntax | Verbose, requires manual property definitions | Concise, supports primary constructors |
Consider a scenario where you want to store employee information and compare two objects:
public class EmployeeClass { public string Name { get; set; } public int Id { get; set; } } public record EmployeeRecord(string Name, int Id); // Using classes var empClass1 = new EmployeeClass { Name = "John", Id = 1 }; var empClass2 = new EmployeeClass { Name = "John", Id = 1 }; Console.WriteLine(empClass1 == empClass2); // Output: False (reference equality) // Using records var empRecord1 = new EmployeeRecord("John", 1); var empRecord2 = new EmployeeRecord("John", 1); Console.WriteLine(empRecord1 == empRecord2); // Output: True (value equality)
By choosing records instead of classes in C#, you can write code that is easier to maintain, less error-prone, and more expressive when dealing with data-centric scenarios.
By default, record properties are immutable. You can, however, create copies of records with modified properties using the with expression:
var original = new Person("Alice", "Johnson", 30); var updated = original with { Age = 31 }; Console.WriteLine(original.Age); // 30 Console.WriteLine(updated.Age); // 31
With C# 10, you can create record structs for value types that benefit from immutability and concise syntax:
public readonly record struct Point(int X, int Y); var p1 = new Point(10, 20); var p2 = new Point(10, 20); Console.WriteLine(p1 == p2); // True
C# record types provide a modern, elegant way to define immutable, value-based objects. They are ideal for scenarios where data consistency and simplicity are essential. By understanding record types in C#, developers can write cleaner, more maintainable, and error-resistant code. Records bridge the gap between classes and functional programming patterns, making them an essential tool for any modern C# developer.
Classes focus on behavior and reference equality, while records focus on immutable data and value equality. Records automatically generate useful methods like Equals() and ToString().
Yes, you can declare properties with setters, but it is not recommended. Records are designed to be immutable by default for consistency.
A record struct is a value type (struct) that benefits from record features such as value-based equality and immutability, introduced in C# 10.
You can use the with expression to create a copy of a record with specific modifications:
var updated = original with { Property = newValue };
Use records when your object is primarily data-centric, immutable, and you want value-based equality. Use classes when behavior, mutability, or inheritance is more important.
Copyrights © 2024 letsupdateskills All rights reserved