首页 > 解决方案 > 具有集合属性的记录类型和具有值语义的集合

问题描述

在 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, "test", new[] {1,2});
Console.WriteLine(r1 == r2); // false, since int[] is a non-record reference type

.Net(或第 3 方)中是否有可以在这种情况下使用的具有值语义的集合类型?我查看了 ImmutableArray 之类的,但它们也没有提供此功能。

标签: c#c#-9.0

解决方案


看起来目前没有这种类型可用。

您可以自己实现它,但如果您需要以生产就绪的方式使用它,请注意其含义。正如@ryanholden8 的回答所证明的那样,这并不像乍一看那么简单!

对于我的用例(作为一个简化的示例),我使用了这个 gist,它装饰了一个 IImutableList 并且可以按如下方式使用:

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

显然要注意对非常大的列表的性能影响。


推荐阅读