与结构初始化和默认参数直观行为 [英] Unintuitive behaviour with struct initialization and default arguments

查看:180
本文介绍了与结构初始化和默认参数直观行为的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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;

上面给出了有效==真,因为默认ARG的构造不叫和对象与标准的默认VAL = 0.0创建的。结果
。如果结构是一类行为是有效==虚假这是我期望的那样。

The above gives valid==true because the constructor with default arg is NOT called and the object is created with the standard default val = 0.0.
If the struct is a class the behaviour is valid==false which is what I would expect.

我发现的行为,并在结构情况下,令人惊奇这种差异尤其是行为和直观的 - 这是怎么回事?什么是对stuct构造默认ARG服务? 如果其用武之地,为什么让这个编译

I find this difference in behaviour and particularly the behaviour in the struct case suprising and unintuitive - what is going on? What does the default arg on the stuct construct serve? If its useless why let this compile?

更新:澄清这里的重点不在行为是什么 - 而是为什么呢?编译没有警告和行为unintuitively。即如果未在新的测试,因为应用的默认ARG()情况下的构造不叫然后点击为什么让它编译?

Update: To clarify the focus here is not on what the behaviour is - but rather why does this compile without warning and behave unintuitively. I.e If the default arg is not applied because in the new Test() case the constructor is not called then why let it compile?

推荐答案

在C#(至少在C#6 - 的看博客帖子),调用新测试()等同于写默认情况下(测试) - 没有构造函数实际上是调用,提供了默认值

In C# (at least until C# 6 - see blog post), invoking new Test() is equivalent to writing default(Test) - no constructor is actually called, the default value is provided.

默认ARG也是没有用处的,什么情况是,它很可能会在编译和执行监督的结果,是由于这样的事实,可选参数是在C#4只加了:

The default arg serves no purpose, what happens is that it is likely the result of an oversight in the implementation of the compiler, due to the fact that optional arguments were only added in C# 4:


  • ,检查的可选参数不与现有的过载冲突的代码是不知道,在结构的情况下,初始化可能发生的冲突的;

  • 这是翻译什么的代码新测试()表示可能是不知道的可选参数的存在;

  • The code that checks that optional arguments do not conflict with already existing overloads is unaware of a possible conflict with the initializer in the case of structs;
  • The code that translates what new Test() means is probably unaware of the existence of optional arguments;

这是事实,编译器执行迄今最优化'新T()'基本上意味着默认(T)当T是一个结构。这实际上是一个错误 - 它总是应该调用实际参数的构造函数,如果有一个 - 这有可能是一直以来,因为它是允许在IL

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.

有关你的榜样,这意味着新测试()由编译器有效地更换默认(测试) - 所以这是一个错误,将被固定在Visual Studio的下一个版本

For your example, it means that new Test() is effectively replaced by the compiler to default(Test) - so that is a bug, which will be fixed in the next version of Visual Studio.

在换句话说,你有一个极端例子。这很可能是看如何在Visual Studio中的下一个版本的行为,因为这种行为正在改变的好时机。

In other words, you have a corner case. That would probably be a good time to look at how that behaves in the next version of Visual Studio, as that behavior is changing.

这篇关于与结构初始化和默认参数直观行为的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆