C# > Language Features by Version > C# 6 to C# 12 Highlights > Record Types (C# 9)

Record Type Declaration and Usage

This snippet demonstrates the basic declaration and usage of record types in C# 9 and later. Records provide a concise syntax for creating immutable data structures with value-based equality.

Basic Record Definition

This example defines a simple record called `Person` with two properties: `FirstName` and `LastName`. The `record` keyword automatically generates properties, a constructor, value-based equality, and a `ToString` method.

public record Person(string FirstName, string LastName);

public class Example
{
    public static void Main(string[] args)
    {
        Person person1 = new Person("John", "Doe");
        Person person2 = new Person("John", "Doe");

        Console.WriteLine(person1);
        Console.WriteLine($"person1 == person2: {person1 == person2}"); // Value-based equality
    }
}

Concepts behind the snippet

Records in C# are a special kind of class that provides value-based equality. This means two record instances are considered equal if all of their properties are equal, regardless of whether they are the same object in memory. Records are inherently immutable, although you can create mutable records as well. They aim to simplify the creation of data-centric types.

Real-Life Use Case Section

Records are ideal for scenarios involving data transfer objects (DTOs), representing immutable entities in a domain model, or implementing value objects. For example, a `Coordinate` record representing a point on a map, or a `Product` record in an e-commerce system.

Best Practices

Favor immutability whenever possible when using records to prevent unintended side effects. Consider using positional records for simple data structures and property-based records with the `init` accessor for more complex scenarios.

When to use them

Use records when you need value-based equality and immutability. They simplify the creation of data structures where the data itself, rather than object identity, is paramount.

Memory footprint

The memory footprint of a record is similar to that of a class with properties. The difference lies in the generated members, such as equality and `ToString`. If you are working with a large number of small, immutable data objects, the memory overhead of records can be slightly less than manually implementing equality and `ToString` in a class.

Alternatives

Before C# 9, you would typically use classes to represent data structures. To achieve value-based equality with classes, you would need to override the `Equals` and `GetHashCode` methods. Records simplify this process.

pros

  • Concise syntax for creating immutable data structures.
  • Automatic value-based equality implementation.
  • Built-in `ToString` method for easy debugging.

cons

  • Can introduce performance overhead due to value-based equality checks, especially with complex objects.
  • Immutability might not be suitable for all scenarios.
  • Requires C# 9 or later.

FAQ

  • Are records reference types or value types?

    Records are reference types, just like classes. However, they are designed to behave like value types due to their value-based equality.
  • Can I make a record mutable?

    Yes, you can make a record mutable by using properties with `set` accessors. However, it's generally recommended to keep records immutable for better maintainability and thread safety.