【问题标题】:C# Init setters don't work on class recordsC# Init setter 不适用于类记录
【发布时间】:2022-01-21 22:17:03
【问题描述】:

我正在尝试在常规记录上使用初始化设置器,但它们似乎不起作用。但是当我添加单词“struct”以使其成为记录结构时,它可以正常工作。这是故意的吗?看起来很奇怪。

这似乎不是视觉故障,因为构建因此失败,并且重新启动 Visual Studio 没有任何区别。添加空括号也无济于事。

【问题讨论】:

  • 您实际上使用了 setter 两次,编译器由于不可变性而阻止了这种情况。您需要使用位置参数new Record(arg1, arg2);
  • 记录构造函数要求您将值作为参数传递给它,而不是作为 init-block 来初始化实例。
  • 请不要在图片链接中发布错误详情。您的问题应该包含代码和错误。

标签: c# record init


【解决方案1】:

我正在尝试在常规记录上使用初始化设置器,但它们似乎不起作用。

您在记录中使用主构造函数语法,并且与任何类构造函数一样,任何时候使用 new 关键字创建实例(与 with 语法相反),您都需要提供值构造函数。您还可以通过初始化语法初始化该值,这只是主构造函数的参数也是 init 属性这一事实的产物。

但是当我添加单词“struct”以使其成为记录结构时,它可以正常工作。这是故意的吗?

是的。将您的记录设为struct 时发生这种变化的原因是 C# 通常对structs 有不同的规则。例如,如果您从未初始化一个结构字段,它只会自动初始化为所有字段都设置为其默认值的状态。这基本上相当于nullstruct,如果您使用default 关键字初始化任何结构变量,也会发生同样的事情。

同样对于structs,C# 始终允许您使用new 关键字,就像为结构调用公共默认(无参数)构造函数一样:如果不存在这样的构造函数,则其行为与 if你用过default。因此,即使您声明了一个主构造函数,您也可以使用忽略该构造函数存在的语法。

【讨论】:

  • 严格来说,结构没有有一个隐式的默认构造函数。该成员不存在,它不是类型的一部分。在这种情况下,编译器允许语法与default(T) 相同,因为没有要调用的构造函数。现在使用 C# 10,您可以显式定义默认构造函数,但如果您不显式定义一个默认构造函数,编译器不会为您生成一个,这与类不同。当你在 C# 10 中显式定义默认构造函数时,new MyStruct()default(MyStruct) 是不同的。
  • 在该示例中,S1 没有无参数的.ctor 成员并使用initobj S1 进行初始化,而S2 有一个无参数的.ctor 成员并使用call instance void S2::.ctor() 进行初始化。
  • @madreflection:感谢您的澄清。我已经更新了我的答案。现在正确吗?
  • 是的。我相信这准确地代表了事物。但是因为您没有提到 C# 10 中结构的默认构造函数,所以我不会删除 cmets。重要的是要意识到现在存在差异。
猜你喜欢
  • 2018-10-29
  • 2020-10-26
  • 1970-01-01
  • 1970-01-01
  • 2014-07-19
  • 1970-01-01
  • 2022-06-10
相关资源
最近更新 更多