gpt4 book ai didi

c# - 结构初始化和默认参数的不直观行为

转载 作者:IT王子 更新时间:2023-10-29 04:49:59 24 4
gpt4 key购买 nike

public struct Test 
{
public double Val;
public Test(double val = double.NaN) { Val = val; }
public bool IsValid { get { return !double.IsNaN(Val); } }
}

Test myTest = new Test();
bool valid = myTest.IsValid;

上面给出了 valid==true 因为没有调用带有默认 arg 的构造函数,并且对象是使用标准默认值 val = 0.0 创建的。
如果结构是一个类,则行为是 valid==false,这是我所期望的。

我发现这种行为差异,尤其是 struct 案例中的行为令人惊讶且不直观 - 这是怎么回事?结构构造上的默认参数有什么用? 如果它没用,为什么要让它编译?

更新:澄清这里的重点不是行为是什么 - 而是为什么这个编译没有警告并且行为不直观。即,如果因为在新的 Test() 情况下未调用构造函数而未应用默认 arg,那么为什么要让它编译?

最佳答案

在 C# 中(至少直到 C# 6 - see blog post ),调用 new Test() 等同于编写 default(Test) - 实际上没有调用构造函数, 提供默认值。

默认 arg 没有任何用处,这很可能是编译器实现疏忽的结果,因为可选参数仅在 C# 4 中添加:

  • 检查可选参数是否与现有重载不冲突的代码不知道在结构的情况下可能与初始化程序发生冲突;
  • 翻译 new Test() 含义的代码可能不知道可选参数的存在;

    • 在深入研究评论后,我注意到 Mads Torgersen 的以下 gem :

      It is true that the compiler implementation has so far "optimized" 'new T()' to mean essentially default(T) when T is a struct. That was actually a bug - it was always supposed to call an actual parameterless constructor if there is one - which there could have been all along, since it is allowed in IL.

      对于您的示例,这意味着 new Test() 被编译器有效地替换为 default(Test) - 所以这是一个错误,将被修复在下一版本的 Visual Studio 中。

换句话说,你有一个极端情况。这可能是查看其在下一版本的 Visual Studio 中的行为方式的好时机,因为该行为正在发生变化。

关于c# - 结构初始化和默认参数的不直观行为,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/27145633/

24 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com