Understanding C# Records with Example

Introduction

The release of C# 9.0 introduced a significant new feature: records. This addition brought a new paradigm for defining data-centric classes, enhancing the language's capabilities, and simplifying the code. This article will delve into C# records, their benefits, and practical usage examples.

What are C# Records?

In C#, a record is a reference type that provides built-in functionality for value equality, immutability, and concise syntax for defining data-centric classes. Unlike traditional classes, records are primarily intended to model data rather than behavior. They offer a way to create immutable objects with value equality semantics, meaning two record instances are considered equal if all their properties are equal.

Key Features of C# Records

  1. Immutability: By default, properties in a record are immutable, meaning once a record is created, its property values cannot be changed. This immutability promotes thread safety and reduces bugs related to state changes.
  2. Value Equality: Records automatically implement value equality. This means that two instances of a record with the same data are considered equal, which is particularly useful for comparing data objects.
  3. Concise Syntax: Records allow for a more straightforward and readable syntax for defining data objects. This reduces boilerplate code and enhances code maintainability.

Defining a Record

Creating a record in C# is straightforward. Here’s an example.

public record Person(string FirstName, string LastName);

This simple line of code defines a Person record with two properties: FirstName and LastName. The compiler automatically generates the necessary constructors, equality members, and immutability semantics.

Working with Records

Let's explore some practical scenarios to understand how records work.

Immutability

var person = new Person("John", "Doe");
// person.FirstName = "Jane"; // This line will cause a compile-time error

The person record's properties cannot be modified after creation, ensuring its immutability.

Value Equality

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

The person1 and person2 records are considered equal because their property values are identical.

With-Expressions

To create a new record with some properties modified, you can use the expression.

var person = new Person("John", "Doe");
var modifiedPerson = person with { LastName = "Smith" };
Console.WriteLine(modifiedPerson); // Output: Person { FirstName = John, LastName = Smith }

The with expression creates a new record instance with the specified properties modified while keeping the rest unchanged.

When to Use Records?

Records are ideal for scenarios where the primary focus is on the data being represented rather than the behaviour. They are particularly useful for,

  • Data transfer objects (DTOs)
  • Immutable data structures
  • Modelling data in functional programming paradigms

Limitations of Records

While records offer numerous benefits, they also have some limitations.

  • Inheritance: Records support inheritance, but their primary purpose is to represent data rather than behaviour, making extensive inheritance hierarchies less common.
  • Performance: In some scenarios, the additional overhead of value equality and immutability may impact performance. Profiling and testing are essential to determine if records are suitable for performance-critical applications.

Conclusion

C# records are a powerful addition to the language, providing a concise, immutable, and value-oriented way to define data-centric classes. They simplify code, reduce boilerplate, and enhance readability, making them a valuable tool for developers. By understanding their features and limitations, you can leverage records effectively in your C# projects, leading to cleaner and more maintainable code.


Similar Articles