2015-10-01 35 views
7

我只注意到以下是可能的書面在Visual Studio 2015年C#,但在此之前我從來沒有見過它:新的C#6對象初始化語法?

public class X 
{ 
    public int A { get; set; } 

    public Y B { get; set; } 
} 

public class Y 
{ 
    public int C {get; set; } 
} 

public void Foo() 
{ 
    var x = new X { A = 1, B = { C = 3 } }; 
} 

我的期望是爲富不得不被這樣實現:

public void Foo() 
{ 
    var x = new X { A = 1, B = new Y { C = 3 } }; 
} 

請注意,不需要撥打new Y

這是C#6中的新功能嗎?我在release notes中沒有看到任何提及,所以也許它一直在那裏?

+0

的可能的複製(http://stackoverflow.com/questions/32342188/c-sharp- object-initialization-bug) –

回答

11

如果您運行此代碼,您將得到一個NullReferenceException。

它不會產生的Y一個實例,它會調用X.B屬性的getter和嘗試的值賦給屬性C.

它總是工作這樣。根據C#5.0語言規範:

成員初始化程序在等號之後指定對象初始值設定項是嵌套對象初始值設定項,即嵌入對象的初始化。不是將新值賦給字段或屬性,而是將嵌套對象初始值設定項中的賦值作爲賦值給字段或屬性的成員。

+0

你是對的,謝謝。因此,我們可以將'X.B'的聲明更改爲'public Y B {get; } = new Y();'此代碼將按預期工作。奇怪的是,我從來沒有注意到這個語法! – jonnystoten

+2

此功能是C#3.0中引入的 – Vova

6

此功能在C#3.0中作爲對象初始值設定項引入。

請參閱第31頁上的示例。的C# Language 3.0 specification 169:[?C#對象初始化錯誤]

Rectangle r = new Rectangle { 
    P1 = { X = 0, Y = 1 }, 
    P2 = { X = 2, Y = 3 } 
}; 

其具有作爲

相同的效果
Rectangle __r = new Rectangle(); 
__r.P1.X = 0; 
__r.P1.Y = 1; 
__r.P2.X = 2; 
__r.P2.Y = 3; 
Rectangle r = __r;