C# tutorials > Modern C# Features > C# 6.0 and Later > What are record types in C# 9.0 and what are their key characteristics?
What are record types in C# 9.0 and what are their key characteristics?
C# 9.0 introduced record types, a new reference type that provides concise syntax for creating immutable data models. Records offer value-based equality, meaning two records are considered equal if their properties have the same values, regardless of their reference. This is a significant departure from classes, where equality is based on reference by default. Records also provide built-in support for non-destructive mutation using the with
expression.
Defining a Record
This code defines a simple record called Person
. It has three properties: FirstName
, LastName
, and Age
. This concise syntax automatically generates properties, a constructor, a deconstructor (for pattern matching), and value-based equality members.
public record Person(string FirstName, string LastName, int Age);
Value-Based Equality
This code demonstrates value-based equality. Even though person1
and person2
are different instances in memory, they are considered equal because their properties have the same values. The ==
operator, in the context of records, performs a deep comparison of the properties.
Person person1 = new("John", "Doe", 30);
Person person2 = new("John", "Doe", 30);
Console.WriteLine(person1 == person2); // Output: True
Non-Destructive Mutation with 'with' Expression
The with
expression allows you to create a new record instance based on an existing one, with some properties modified. In this example, person2
is created as a copy of person1
, but with the Age
property updated to 31. Crucially, person1
remains unchanged. This ensures immutability.
Person person1 = new("John", "Doe", 30);
Person person2 = person1 with { Age = 31 };
Console.WriteLine(person1);
Console.WriteLine(person2);
Concepts Behind the Snippet
Real-Life Use Case: Data Transfer Objects (DTOs)
Records are excellent for representing DTOs in APIs and microservices. Since DTOs primarily hold data, the value-based equality and concise syntax of records make them a natural fit. The immutability ensures data integrity as it moves between layers.
Best Practices
with
expression for non-destructive updates to maintain immutability.
Interview Tip
Be prepared to discuss the differences between records and classes, particularly regarding equality and immutability. Understand the benefits of records in data-centric scenarios and how the with
expression works. Mention the performance implications of value-based equality (potentially slower than reference equality for complex objects).
When to Use Records
Use records when:
Memory Footprint
The memory footprint of a record is generally similar to that of a class with auto-implemented properties. There might be a slight overhead due to the generated equality and deconstruction methods, but it's usually negligible. However, excessive use of the with
expression can lead to increased memory consumption if many new record instances are created without proper garbage collection.
Alternatives
Alternatives to records include:
Pros
with
expression).
Cons
FAQ
-
What's the difference between a record and a class in C#?
The key differences are: records have value-based equality (equality is determined by the properties, not the reference), records are designed to be immutable (although they can be mutable), and records have more concise syntax. Classes have reference-based equality by default and are generally mutable.
-
Can I make a record mutable?
Yes, you can make a record mutable by using
set
accessors on its properties. However, it's generally recommended to keep records immutable to leverage their benefits. -
What is a positional record?
A positional record is a record where the constructor parameters define the properties directly. For example:
public record Person(string FirstName, string LastName);
This is even more concise than the example in 'Defining a Record'.