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

2024-03-07

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这正是我所期望的。

我发现这种行为差异,特别是结构案例中的行为令人惊讶且不直观 - 发生了什么?结构体上的默认参数有什么作用?如果它没用为什么要让它编译?

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


在 C# 中(至少到 C# 6 -请参阅博客文章 http://blogs.msdn.com/b/csharpfaq/archive/2014/11/20/new-features-in-c-6.aspx),调用new Test()相当于写作default(Test)- 没有实际调用构造函数,提供默认值。

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

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

    • 在深入研究评论后,我注意到以下宝石麦兹·托格森 http://blogs.msdn.com/b/csharpfaq/archive/2014/11/20/new-features-in-c-6.aspx?PageIndex=2#comments:

      确实,到目前为止,编译器实现已经“优化”了“new T()”,当 T 是一个结构时,其本质上意味着 default(T)。这实际上是一个错误 - 如果有的话,它总是应该调用一个实际的无参数构造函数 - 这可能一直存在,因为它在 IL 中是允许的。

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

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

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

结构初始化和默认参数的不直观行为 的相关文章

随机推荐