c# - 具有集合属性的记录类型和具有值语义的集合
问题描述
在 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 之类的,但它们也没有提供此功能。
解决方案
看起来目前没有这种类型可用。
您可以自己实现它,但如果您需要以生产就绪的方式使用它,请注意其含义。正如@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
显然要注意对非常大的列表的性能影响。
推荐阅读
- r - R中的数据框,不同的行数和列数
- email - 我可以为我的新域购买电子邮件地址吗?
- java - 通过 JLabel 将图像添加到 JWindow 不会出现在屏幕上
- git - 恢复 git lfs 存储
- python - 根据来自其他 DF 的值选择 DF 行
- twitter - Twitter 身份验证在本地工作,但在 Vercel 服务器中不工作 (Next.JS)
- c++ - 从 C++ 协程中获取协程句柄的最有效方法
- reporting-services - SSRS 从 SQL 存储过程返回值获取结果
- javascript - 使用外部 javascript 代码在 Chrome 控制台上运行代码段
- android-studio - Android Studio 应用程序图标未在新的 Android 模型中显示