My proposed syntax for record types in C#
With the impending release of C# 6.0 and all its new features, I have been thinking about what might come in the next version of C# (v7.0, I’m guessing). There has been talk in the Roslyn forums about things such as pattern matching and record types (the latter being especially important since the primary constructors feature was dropped from C# 6.0).
Below is a quick sketch of how I think record classes should work in C#. You can probably tell that I spend a lot of time programming functionally, because I’ve included a number of syntax features here to make immutability a very easy option.
Note: I’m not sure that the “class” keyword is even needed any more. Contrast: “public record class Person” vs “public record Person”
public record class Person { string Name { get; set; } DateTime DoB { get; } bool IsRobot { get; set; } = false; } // Note the lack of visibility modifiers. Like an interface, everything is public in a record class var john = new Person { Name = "John" // Compiler error: A value for "DoB" has not been supplied } // This is legal. IsRobot is "optional" because it has a default value in the class definition var joe = new Person { Name = "Joe", DoB = DateTime.Yesterday } joe.Name = "Suzy" // Legal: Name is "mutable" because it has a public setter in the class definition. joe.DoB = DateTime.Now // Compiler error: "DoB" has no public setter. DoB is "immutable" public record class Point { double X { get; } double Y { get; } } var origin = new Point { X = 0.0, Y = 0.0 } var location = new Point { X = 0.0, Y = 0.0 } origin == location // => true. Records have auto-generated structural equality and GetHashcode methods origin.ToString() // => "Point { X = 0.0, Y = 0.0 }". Records have an auto-generated ToString() method (can be overridden). // Custom members can be defined, both properties and methods. Note that only auto-implemented properties are required // when instantiating the record. public record class Point3D { double X { get; } double Y { get; } double Z { get; } override String ToString() { return $"({X}, {Y}, {Z})"; } double Dist => Sqrt(X * X + Y * Y + Z * Z); }