Search code examples
c#immutabilityrecord

Why are record classes immutable by default, but record structs are not, in C#?


I was taught that structs should almost always be immutable, so this unusual behaviour of record classes vs. record structs threw me off guard.

Using a record class...

record class Person(string FirstName, string LastName);
Person p = new("John", "Smith");
p.FirstName = "Jack" // Not allowed!

Using a record struct...

record struct Person(string FirstName, string LastName);
Person p = new("John", "Smith");
p.FirstName = "Jack" // Fine!

Using a readonly record struct...

readonly record struct Person(string FirstName, string LastName);
Person p = new("John", "Smith");
p.FirstName = "Jack" // Now allowed!

Why are non readonly record structs mutable by default, and why doesn't the same behaviour apply for record classes?

Edit: I guess what I'm asking here is, why is the syntax... weird?

For example, it would seem more logical like:

  • record class - mutable reference type with value semantics.
  • readonly record class - immutable reference type with value semantics.
  • record struct - mutable value type with value semantics.
  • readonly record struct - immutable value type with value semantics.

Solution

  • If you use the positional syntax for defining a record class, it's properties are immutable

    record class Point(int X, int Y);
    

    It defaults to having property accessory of {get; init;}

    If you declare this in a traditional way (without positional parameters), you can specify your property accessors:

    record class Point
    {
        int X {get; set;}
        int Y {get; set;}
    }
    

    You can mix and match these two styles, but bear in mind that if you provide any positional parameters, they will become the parameters on the auto implemented constructor, and any other properties will not be set.

    I realise this doesn't actually answer the question as to why this behaviour exists, I'm just hoping that people that read this won't come away with the conclusion that record class is immutable.