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

Viewed 112

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.
1 Answers

Taken directly from a Microsoft MVP Engineer İlkay İlknur:

Most of the generated code looks similar to the record classes. However, there is one difference between record structs and record classes. The generated properties in record structs are mutable by default. The reason behind this decision was to be consistent with tuples. Tuples are like anonymous record structs with similar features. On the other hand, struct mutability does not carry the same level of concern as class mutability does. That's why the C# team decided to make record struct properties mutable by default. However, if you need immutable record structs, you can use the readonly keyword.

record-structs-in-csharp

Related