使用C# 9中的记录“with”表达式,我可以复制并添加到新的派生实例中吗?

23

假设我有以下内容:

public record Settings 
{
  public int Setting1 { get; init; }
}

public record MoreSettings : Settings
{
  public string Setting2 { get; init; }
}
...

var settings = new Settings { Setting1 = 1 };

// This is an error - CS0117
MoreSettings moreSettings = settings with { Setting2 = "A string setting" };

有没有一种简洁的方法来实现这个?我的语法是否有误?
显然,在这个人为构造的情况下,我可以手动复制每个基本属性。


在这个人为构造的情况下,我可以手动复制每个基本属性。
var moreSettings = new MoreSettings { Setting1 = settings.Setting1, Setting2 = "A String!" };

但是如果基本记录类型有很多属性呢?


这是不被支持的。在基础记录有大量属性的情况下,您将不得不逐个复制它们。您可能想跳转到 GitHub 并提出建议,或查找现有建议,并为其投票。 - Lasse V. Karlsen
这是不可能的,在一般情况下也不行——如果MoreSettings没有定义无参构造函数,会怎么样呢? - Yair Halberstadt
2
这就是我担心的。我在Typescript领域花费了太多时间。 - John Maillet
1个回答

40

根据您的原始问题,

MoreSettings moreSettings = settings with { Setting2 = "A string setting" };

with关键字在更改指定属性之前,内部确保调用类型的拷贝构造函数。在示例中,Settings记录没有名为Settings2的属性,因此不允许这样做。关于第二种方法,如果基类有很多属性,您可以为MoreSettings记录引入另一个构造函数,该构造函数接受Settings实例作为解决方法,以避免像OP中给出的第二个示例中添加每个属性。相反,您可以,
public record MoreSettings : Settings
{
   public MoreSettings(Settings parent) : base(parent) { }
   public string Setting2 { get; init; }
}

现在你可以将其称之为

MoreSettings moreSettings = new MoreSettings(settings) { Setting2 = "A string setting" };

您还可以利用 C# 9 中的目标类型 new 表达式来删除右侧的 MoreSettings。

MoreSettings moreSettings = new (settings)  { Setting2 = "A string setting" };

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接