public class Person
{
public string FirstName {set; get;}
public string LastName {set; get;}
public int Age;
}
以前對Person類成員賦值的過程是這樣的:
Person person = new Person();
person.FirstName = "Jack";
person.LastName = "li";
person.Age = 11;
利用object initializer的新特性,可以將以上實現過程寫成
Person person = new Person() {FirstName = "Jack", LastName = "li", Age = 11};
可以進一步寫成
Person person = new Person {FirstName = "Jack", LastName = "li", Age = 11};
這個代碼生成的IL是第一個生成的IL執行過程是一樣的。這就可以簡化我們的代碼,讓本來幾行才能寫完的代碼一行寫完。
為了更好的掌握object initializer,以下幾點需要注意:
1.對象初始化器可以只給部分成員賦值麼,賦值時不分先後順序;
2.對旬初始化只能對public, internal類型的屬性數據成員賦值;
3:對象初始化器是否可以結合構造函數一起使用, 構造函數先執行。
Collection Initializers
明白了對象初始化器,就比較好明白集合初始化器,如
var strList = new List<string>{"a", "b"}
var persons = new List<Person>
{
new Person{FirstName="yang"},
new Person{LastName="peng"}
}
集合初始化構造器中可以構造集合的一項為空值.
var persons = new List<Person>
{
new Person{FirstName="yang"},
null;
new Person{LastName="peng"}
}
任何東西都不是完美的,初始化構造器也是有利有弊。最大的好處是和linq結合,可以將linq寫得比較簡潔。我認為不好的地方是set property對外暴露了接口,如果只是初始化一次,構造函數就可以勝任這個工作,而且具有更好的封裝性。另一點需要注意的是對象初始化並不是一定要求數據成員實現set property,有些情況下get也是可以的。看下面這個例子:
public class Contact
{
private List<string> names= new List<string>{"first"};
public List<string> Names
{
get { return phoneNumbers; }
}
}
var contact = new Contact{ Names = {"second"}};
這個Names就是執行的get操作,相當於是contact.Names.Add("second");在這個例子中也暴露出一個問題:當內部數據成員IEnumerable時,不要通過get方式直接返回該成員,這是很不安全的。因為外部得到該成員後,一旦修改,相當於就是直接修改類成員。這破壞了數據的封裝性。
任何新事物都是一把雙刃劍,關鍵取決於使用的人。只有對新特性了如指掌,才可以游刃有余地恰當使用。