C# Record Types

C# Record Types

Records are a type of reference or value type introduced in C# to simplify the creation of immutable objects.

They can be declared using record for reference types and record struct for value types.

Records automatically provide a suite of benefits that traditional classes do, but with less boilerplate code and more clarity.

public record Person(string FirstName, string LastName, int Age);
public record struct Point(double X, double Y, double Z);        

Features of Record Types

Immutability by Default

Records in C# ensure that properties can only be set during object initialization using the init keyword. This design helps prevent bugs that occur due to unintended modifications, ensuring safer and more predictable code, particularly in multi-threaded environments.

public record Person(string FirstName, string LastName, int Age);
Person person = new("John", "Doe", 30);
// person.Age = 35; // This would result in a compile-time error        

Value-based Equality

Unlike classes that use reference equality, records provide value equality out of the box. This means two record instances are considered equal if all their property values are the same.

var person1 = new Person("John", "Doe", 30);
var person2 = new Person("John", "Doe", 30);
Console.WriteLine(person1 == person2); // Outputs: True        

Nondestructive Mutation

Records support modifications through with expressions, allowing the creation of new instances based on existing ones with altered property values without changing the original record.

Person updatedPerson = person with { Age = 35 };        

Built-in Functionality

C# records come with automatically generated methods like ToString, GetHashCode, and Equals, and support deconstruction out of the box. This functionality reduces the need to manually override these methods, ensuring consistency and reducing potential errors.

Console.WriteLine(person.ToString()); // Outputs: Person { FirstName = John, LastName = Doe, Age = 30 }        

Deconstructor in Records

When you define a record in C#, the compiler automatically generates a deconstructor method if the record is defined with positional parameters. This automatic deconstructor corresponds to the parameters defined in the primary constructor of the record.

Example of Automatic Deconstruction

Here’s a simple record with automatic deconstruction:

public record Person(string FirstName, string LastName, int Age);        

You can then deconstruct this record like so:

var person = new Person("John", "Doe", 30);
var (firstName, lastName, age) = person;  // Deconstruction        

In this example, firstName, lastName, and age will be assigned the values from the respective properties of the person object.

Concise Syntax

One of the main attractions of records is their concise syntax. They can be defined in a single line, reducing clutter and making the code easier to read and maintain.

Practical Applications of Record Types

Record types are ideal for scenarios where data integrity and consistency are paramount.

They are particularly well-suited for use as

  • Data Transfer Objects (DTOs)
  • Entities in domain-driven design
  • for ensuring thread-safe operations in concurrent applications and any situation where an immutable data structure is beneficial

However, they are not suited for all scenarios, such as when mutable objects are required, like with certain ORM (Object-Relational Mapping) frameworks.

Reference:

https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/builtin-types/record#positional-syntax-for-property-definition

To view or add a comment, sign in

More articles by Jeevanandan J

Others also viewed

Explore content categories