Visual Studio 2015缺少新关键字 - 没有编译器错误

mus*_*ium 0 c# visual-studio object-initializer c#-6.0

当我犯了一个愚蠢的错误时,我正在处理我们的一个新应用程序......我忘了写一个对象初始化程序中的"new ClassName".奇怪的是VS刚刚编译了代码......没有任何错误或警告.(我用过VS 2015,.Net 4.5.2)

我的代码:

var target = new MyClass
{
    MyValues = new List<MyOtherClass>
    {
        new MyOtherClass
        {
            Start = new DateTimeValue
            {
                DateTime = new DateTime(2015, 08, 23)
            },
            End = {
                DateTime = new DateTime(2015, 08, 23)
            }
        }
    }
};
Run Code Online (Sandbox Code Playgroud)

(开始和结束都是DateTimeValue类型)

当我启动应用程序时,此代码抛出了NullReferenceException.(添加"new DateTimeValue"修复了问题).为什么编译器没有错误?

Jon*_*eet 9

那里根本没有错.它使用对象初始End值设定项,使用现有值设置属性,而不是为其分配End.您的代码相当于:

var tmp0 = new MyClass();
var tmp1 = new List<MyOtherClass>();
var tmp2 = new MyOtherClass();
var tmp3 = new DateTimeValue();
tmp3.DateTime = new DateTime(2015, 8, 23);
// Note the assignment to Start here
tmp2.Start = tmp3;

// No assignment to End -
// it's calling the End "getter" and then the DateTime "setter" on the result
tmp2.End.DateTime = new DateTime(2015, 8, 23);
tmp1.Add(tmp2);
tmp0.MyValues = tmp1;
var target = tmp0;
Run Code Online (Sandbox Code Playgroud)

从C#5规范,第7.6.10.2节:

在等号后面指定对象初始值设定项的成员初始值设定项是嵌套对象初始值设定项,即嵌入对象的初始化.而不是为字段或属性分配新值,嵌套对象初始值设定项中的赋值被视为对字段或属性成员的赋值.

这正是你在这里做的 - { DateTime = ... }部分是一个对象初始化器.