Init-only setters in C#
2023-06-11T21:50:37 - Vicky Chhetri
An init-only setter in a property declaration uses the init keyword instead of the set keyword:
class Foo { public int ID { get; init; } }
This behaves like a read-only property, except that it can also be set via an object initializer:
var foo = new Foo { ID = 123 };
This makes it possible to create immutable (read-only) types that can be populated via an object initializer instead of a constructor, and helps to avoid the antipattern of constructors that accept a large number of optional parameters. Init-only setters also allow for nondestructive mutation when used in records.
Records
A record is a special kind of class that’s designed to work well with immutable data. Its most special feature is that it supports nondestructive mutation via a new keyword (with):
Point p1 = new Point (2, 3);
Point p2 = p1 with { Y = 4 }; // p2 is a copy of p1, but with Y set to 4
Console.WriteLine (p2); // Point { X = 2, Y = 4 }
record Point
{
public Point (double x, double y) => (X, Y) = (x, y);
public double X { get; init; }
public double Y { get; init; }
}
In simple cases, a record can also eliminate the boilerplate code of defining properties and writing a constructor and deconstructor. We can replace our Point record definition with the following, without loss of functionality
record Point (double X, double Y);
Like tuples, records exhibit structural equality by default. Records can subclass other records and can include the same constructs that classes can include. The compiler implements records as classes at runtime.