2017-07-31 73 views
20

我一直使用C#了一段時間,但最近發現,我的單元測試一個的行爲已發生更改,這取決於集合的變化初始化器表達我用:這兩個集合初始化表達式的變體有什麼區別?

  • var object = new Class { SomeCollection = new List<int> { 1, 2, 3 } };
  • var object = new Class { SomeCollection = { 1, 2, 3 } };

直到這一點,我認爲第二種形式只是語法糖,在語義上等同於第一種形式。但是,這兩種形式之間的切換導致我單元測試失敗。

下面的示例代碼演示了這一點:

void Main() 
{ 
    var foo1 = new Foo { Items = new List<int> { 1, 2, 3} }; 
    var foo2 = new Foo { Items = { 1, 2, 3 } }; 

    foo1.Dump(); 
    foo2.Dump(); 
} 

class Foo 
{ 
    public List<int> Items { get; set; } 
} 

當我運行此,第一分配工作正常,但在NullReferenceException第二結果。

我的直覺是,幕後的編譯器處理這兩個詞語,因爲這:

var foo1 = new Foo(); 
foo1.Items = new List<int> { 1, 2, 3 }; 

var foo2 = new Foo(); 
foo2.Items.Add(1); 
foo2.Items.Add(2); 
foo2.Items.Add(3); 

是這個假設是否準確?

+0

,將幫助您:HTTP:/ /www.c-sharpcorner.com/article/C-Sharp-heaping-vs-stacking-in-net-part-iii/ –

回答

22

是的,你的假設是準確的。如果一個對象初始化只是有:

{ 
    Property = { ... } 
} 

而不是

{ 
    Property = expression 
} 

那麼二傳手的財產不使用 - 在吸氣被使用,那麼無論是Add方法調用,或者屬性在返回值中設置。所以:

var foo = new Foo 
{ 
    Collection = { 1 } 
    Property = 
    { 
     Value = 1 
    } 
}; 

等同於:

// Only the *getters* for Collection and Property are called 
var foo = new Foo(); 
foo.Collection.Add(1); 
foo.Property.Value = 1; 

相比之下,與:

var foo = new Foo 
{ 
    Collection = new List<int> { 1 }, 
    Property = new Bar { Value = 1 } 
}; 

這相當於:

// The setters for Collection and Property are called 
var foo = new Foo(); 
foo.Collection = new List<int> { 1 }; 
foo.Property = new Bar { Value = 1 }; 
+1

不應該等同於新的集合還是它只是添加? –

相關問題