[英]What is the difference between these two variations of collection initialiser expressions?
我一直在使用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);
這個假設准確嗎?
是的,你的假設是准確的。 如果對象初始化程序只有:
{
Property = { ... }
}
而不是
{
Property = expression
}
然后不使用屬性的setter - 使用getter ,然后調用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 };
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.