C# 10 中的结构无参数构造函数和字段初始值设定项

Struct parameterless constructor and field initializers in C# 10

提问人:Bartosz 提问时间:11/9/2021 最后编辑:Bartosz 更新时间:11/9/2021 访问量:685

问:

C# 10 使为结构声明无参数构造函数和字段初始值设定项成为可能。根据语言参考,当您声明字段初始值设定项但没有显式无参数构造函数时,会发生什么情况:

如果未显式声明无参数构造函数,则结构类型将提供无参数构造函数,其行为如下所示:

  • 如果结构类型具有显式实例构造函数或没有字段初始值设定项,则隐式无参数构造函数将生成结构类型的默认值,而不考虑字段初始值设定项 (...) 。

  • 如果结构类型没有显式实例构造函数,并且具有字段初始值设定项,则编译器将合成一个公共无参数构造函数,该构造函数执行指定的字段初始化 (...) 。

以下代码输出:1

struct S {
    public int X = 1;
}

class Program {
    static void Main() { System.Console.WriteLine(new S().X); }
}

以下代码输出:0

struct S {
    public int X = 1;
    public S(int x) { X = x; }
}

class Program {
    static void Main() { System.Console.WriteLine(new S().X); }
}

这与上面引用的规范完全一致,但我觉得这不合逻辑,所以我的问题是:为什么?为什么隐式无参数构造函数会根据是否有其他实例构造函数而具有不同的行为?为什么它不能总是考虑字段初始值设定项,即使有其他实例构造函数?

c 结构 默认构造函数 c#-10.0

评论

1赞 Jeroen Mostert 11/9/2021
此处讨论:“[..]合成无参数构造函数会对具有主构造函数的记录结构产生不良的连锁反应:无参数构造函数会在那里做什么?它没有任何可以调用主构造函数的东西,并且会导致语义混乱“(以及其他考虑因素)。
1赞 Bartosz 11/9/2021
谢谢,我没有找到。但我不相信这个论点。他们希望避免将语义与记录结构混淆,因此他们在所有结构中引入了其他令人困惑的语义......
0赞 Jeroen Mostert 11/9/2021
他们还希望能够轻松地用记录结构替换元组,这就是为什么记录结构默认具有可变属性,而类记录保持不可变的原因。有很多不喜欢的东西。:P
1赞 cremor 1/31/2022
似乎 C# 团队同意这个设计是一个错误的决定,并将它更改为从不合成无参数构造函数。资料来源:github.com/dotnet/csharplang/blob/main/meetings/2022/...

答: 暂无答案