问题描述
在c#9中,我们现在(最终)具有记录类型:
public record SomeRecord(int SomeInt,string SomeString);
这为我们提供了诸如值语义之类的好东西:
var r1 = new SomeRecord(0,"zero");
var r2 = new SomeRecord(0,"zero");
Console.WriteLine(r1 == r2); // true - property based equality
在尝试使用此功能时,我意识到定义(非字符串)引用类型的属性可能会导致违反直觉的行为(即使您可以仔细考虑也可以完全解释):
public record SomeRecord(int SomeInt,string SomeString,int[] SomeArray);
var r1 = new SomeRecord(0,"test",new[] {1,2});
var r2 = new SomeRecord(0,2});
Console.WriteLine(r1 == r2); // false,since int[] is a non-record reference type
在这种情况下,.Net(或第3方)中是否存在具有值语义的集合类型?我看过ImmutableArray之类的东西,但它们也不提供此功能。
解决方法
当前似乎没有此类可用。不过,推出自己的游戏并不难。例如,请参见this gist,它装饰了一个IImutableList,可以按如下方式使用:
var r1 = new SomeRecord(0,"test",new[] { 1,2 }.ToImmutableList().WithValueSemantics());
var r2 = new SomeRecord(0,2 }.ToImmutableList().WithValueSemantics());
Console.WriteLine(r1 == r2); // true
显然要注意很大列表的性能影响。
,没有开箱即用的解决方案。您可以尝试从中得出 Collection。 Microsoft专门针对您不想创建整个样板(添加,删除等)的情况进行了此操作。您可以将我们的方法用于相同的概念: ValueCollection.cs
现在也可以通过方便的package
使用