The record type is a feature introduced in C# 9.0 that allows defining a reference type focused on immutability and structural equality.
Unlike traditional classes, records are designed to represent data, not behaviors. This makes them suitable for modeling data, for example.
Key Characteristics of Record Types
Immutability by Default: record types are immutable by default, meaning their properties are set once at creation time and cannot be modified later.
Structural Equality: record types implement structural equality, meaning two instances of a record are considered equal if their properties have the same values, unlike reference equality which applies to classes.
Deconstruction: record types support deconstruction, allowing easy extraction of values from a record into individual variables.
Pattern Matching: records allow pattern matching which facilitates value comparison and data extraction in pattern matching operations.
How to Use Record
Defining a Record
To define a record type, the record keyword is used followed by the type name and the property list. Here is a basic example:
public record Person(string Name, int Age);
In this example,
Personis arecordwith two properties:NameandAge.- The constructor, properties, and equality methods are automatically generated by the compiler.
Accessing Properties
Accessing the properties of a record is done directly, as in classes:
Console.WriteLine(person.Name); // Output: Ana
Console.WriteLine(person.Age); // Output: 30
Deconstruction
You can deconstruct a record into its individual components using deconstruction syntax:
var (name, age) = person;
Console.WriteLine($"Name: {name}, Age: {age}"); // Output: Name: Ana, Age: 30
Copy with Modification
Although records are immutable, you can create a copy of a record with some modifications using the with expression.
var product = new Product("Monitor", 200.00m);
var modifiedProduct = product with { Price = 180.00m };
Console.WriteLine(modifiedProduct.Price); // Prints 180.00
Structural Equality
Two instances of a record are equal if their properties have the same values:
var person1 = new Person("Ana", 30);
var person2 = new Person("Ana", 30);
var person3 = new Person("Luis", 25);
Console.WriteLine(person1 == person2); // Output: True
Console.WriteLine(person1 == person3); // Output: False
records automatically override the Equals and GetHashCode methods to provide structural equality.
Immutability
By default, the properties of a record are immutable. This means they cannot be modified once the instance is created.
var product = new Product("Tablet", 300.00m);
// product.Price = 250.00m; // Compilation error: cannot modify a read-only property
Record Inheritance
records also support inheritance, allowing the creation of a record hierarchy:
public record Employee(string Name, int Age, string Position) : Person(Name, Age);
In this example, Employee inherits from Person and adds an additional property Position. Inheritance in records allows reusing properties and behaviors while maintaining immutability and structural equality.
Pattern Matching
records allow the use of pattern matching to compare values and extract data:
public void ShowPerson(Person person)
{
if (person is Person { Age: >= 18 } adult)
{
Console.WriteLine($"{adult.Name} is an adult.");
}
else
{
Console.WriteLine($"{person.Name} is not an adult.");
}
}
In this example, the pattern match { Age: >= 18 } checks if the Age property is greater than or equal to 18 and extracts the instance into a variable adult if true.
