C#使用匿名对象初始化对象,编译器的奇怪行为

时间:2017-05-22 17:44:34

标签: c# .net

我注意到C#编译器的一个奇怪的行为,我无法解释。

假设您想以这种方式初始化一个新对象:

    Type1 testObj = new Type1 { 
        Prop1 = "TEST",
        Prop2 = new Type2 { Prop = "TEST2" }

    };

一切都很顺利。编译器不会抱怨并且不会抛出运行时异常。

我尝试通过从代码中删除显式new Type2以类似的方式进行初始化,如下所示:

    Type1 testObj = new Type1 { 
        Prop1 = "TEST",
        Prop2 = { Prop = "TEST2" }

    };

编译器不会抱怨,但在运行时会抛出错误:

  

System.NullReferenceException:未将对象引用设置为实例   一个对象。

我注意到我无法移除new Type1因为在这种情况下编译器会抱怨。当我删除" new"时,编译成功。属性初始化中的关键字,不在主对象中。

Visual Studio没有向我显示任何输入错误并且正确地向我建议了对象属性(.NET Fiddle也是如此)因为类型似乎是推断的(并且工具提示提供了关于此的正确信息)。

这是一个有效的演示: https://dotnetfiddle.net/vnlI20

这是一个无效的演示: https://dotnetfiddle.net/0CraIU

有人可以解释这种行为吗? 在没有任何编译器或运行时错误的情况下,是否存在可以避免使用new关键字的情况? (这会很酷!:))

1 个答案:

答案 0 :(得分:3)

这是因为您没有创建新的Prop2。相反,您要为Prop2.Prop分配一个新值,该值因Prop2为空而失败。

Prop2 = { Prop = "TEST2" }

类似于:

testObj.Prop2.Prop = "TEST2";

由于上述原因而失败。

new ...变体实际上是:

Type1 testObj = new Type1();
testObj.Prop1 = "TEST",
var x = new Type2();
x.Prop = "TEST2";
testObj.Prop2 = x;