In c# 9, we now (finally) have record types:
public record SomeRecord(int SomeInt, string SomeString);
This gives us goodies like value semantics:
var r1 = new SomeRecord(0, "zero"); var r2 = new SomeRecord(0, "zero"); Console.WriteLine(r1 == r2); // true - property based equality
While experimenting with this feature, I realized that defining a property of a (non-string) reference type may lead to counter-intuitive (albeit perfectly explainable if you think it through) behaviour:
public record SomeRecord(int SomeInt, string SomeString, int[] SomeArray); var r1 = new SomeRecord(0, "test", new[] {1,2}); var r2 = new SomeRecord(0, "test", new[] {1,2}); Console.WriteLine(r1 == r2); // false, since int[] is a non-record reference type
Are there collection types with value semantics in .Net (or 3rd party) that may be used in this scenario? I looked at ImmutableArray and the likes, but these don't provide this feature either.
C# 9 introduces records, a new reference type that you can create instead of classes or structs. C# 10 adds record structs so that you can define records as value types. Records are distinct from classes in that record types use value-based equality.
“Record types let you offer different business processes, picklist values, and page layouts to different users. You might create record types to differentiate your regular sales deals from your professional services engagements, offering different picklist values for each.
Because a record type is immutable, it is thread-safe and cannot mutate or change after it has been created. You can initialize a record type only inside a constructor. You can declare a record using the record keyword as shown in the code snippet below.
Class vs Record The main difference between class and record type in C# is that a record has the main purpose of storing data, while class define responsibility. Records are immutable, while classes are not.
It looks like there is currently no such type available.
You can implement this yourself, but beware of the implications if you need this in a production-ready way. It's not so simple as it may seem at first sight, as this answer by @ryanholden8 demonstrates!
For my use case (and as a simplified example) I went along with this gist which decorates an IImutableList and can be used as follows:
var r1 = new SomeRecord(0, "test", new[] { 1, 2 }.ToImmutableList().WithValueSemantics()); var r2 = new SomeRecord(0, "test", new[] { 1, 2 }.ToImmutableList().WithValueSemantics()); Console.WriteLine(r1 == r2); // true
Obviously beware of the performance implications for very large lists.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With