Let’s go through records and init-only properties, introduced in C# 9, which are designed to make immutable data modeling easier and cleaner.


πŸ“Œ 1. What Are Records?

  • A record is a reference type like a class, but optimized for storing data.

  • Records provide:

    • Immutable by default

    • Value-based equality (two records with same data are equal)

    • Concise syntax for defining properties

Example: Basic Record

public record Person(string FirstName, string LastName);
 
class Program
{
    static void Main()
    {
        var p1 = new Person("Alice", "Smith");
        var p2 = new Person("Alice", "Smith");
 
        Console.WriteLine(p1 == p2); // True (value-based equality)
        Console.WriteLine(p1);       // Person { FirstName = Alice, LastName = Smith }
    }
}
  • Unlike classes, == compares property values, not references.

πŸ“Œ 2. init-only Properties

  • init is a modifier for properties that allows them to be set only during initialization, not modified afterward.

  • Works well with records and immutable patterns.

Example

public record Car
{
    public string Make { get; init; }
    public string Model { get; init; }
}
 
class Program
{
    static void Main()
    {
        var car = new Car { Make = "Toyota", Model = "Corolla" };
 
        // car.Make = "Honda"; // ❌ Error: init-only property
        Console.WriteLine($"{car.Make} {car.Model}");
    }
}
  • You can set init properties only during object creation or in object initializer.

πŸ“Œ 3. Combining Records & init-only Properties

public record Book
{
    public string Title { get; init; }
    public string Author { get; init; }
}
 
class Program
{
    static void Main()
    {
        var book1 = new Book { Title = "1984", Author = "George Orwell" };
        var book2 = book1 with { Title = "Animal Farm" }; // "with-expression" creates a copy with changes
 
        Console.WriteLine(book1); // Book { Title = 1984, Author = George Orwell }
        Console.WriteLine(book2); // Book { Title = Animal Farm, Author = George Orwell }
    }
}
  • The with expression is specific to records and allows immutably modifying a copy of a record.

πŸ“Œ 4. Key Features of Records

FeatureNotes
Immutable by defaultUse init to set values at creation
Value equalityTwo records with same properties are equal
DeconstructionCan deconstruct into individual properties
Concise syntaxPositional records (record Person(string FirstName, string LastName))
with expressionsCreate modified copies of records

πŸ“Œ 5. Analogy

  • Think of a record as a snapshot of data:

    • Once created, the snapshot doesn’t change.

    • If you want a β€œnew version,” you copy it and change only the fields you need (with expression).


βœ… Summary:

  • Records = immutable, data-focused reference types with value equality.

  • init-only properties = allow setting values only during initialization.

  • Together, they simplify immutable data modeling, reduce boilerplate, and make equality comparisons intuitive.


If you want, I can make a diagram comparing class vs record vs record with init properties so you can see differences in mutability and equality visually.

Do you want me to make that diagram?