C# 對(duì)象初始化器
考慮下面的簡單類定義:
public class Animal
{
public string Name { get; set;)
public int Age { get; set; }
public double Weight { get; set; }
}
這個(gè)類有3個(gè)屬性,用第10章介紹的自動(dòng)屬性語法來定義。如果希望實(shí)例化和初始化這個(gè)類的一個(gè)對(duì)象實(shí)例,就必須執(zhí)行如下幾個(gè)語句:
Animal animal = new Animal 0;
animal. Name = "Benjamin";
animal. Age = 42;
animal. Weight = 185.4;
如果類定義中未包含構(gòu)造函數(shù),這段代碼就使用c#編譯器提供的默認(rèn)無參數(shù)構(gòu)造函數(shù)。為了簡化這個(gè)初始化過程,可提供一個(gè)合適的非默認(rèn)構(gòu)造函數(shù):
public class Animal
{
public Animal (string name, int ago, double weight)
{
Name = name;
Age = age;
Weight = weight;
}
...
}
這樣就可以編寫代碼,把實(shí)例化和初始化合并起來:
Animal animal = new Animal("Noa", 5, 45.2);
這段代碼工作得很好,但它會(huì)強(qiáng)制使用Animal類的代碼使用這個(gè)構(gòu)造函數(shù),這將阻止前面使用無參構(gòu)造函 數(shù)的代碼運(yùn)行。常需要提供無參構(gòu)造函數(shù),在必須序列化類時(shí)尤其如此:
public class Animal
{
public Animal() {}
...
}
現(xiàn)在可以用任意方式來實(shí)例化和初始化Animal類,但己在最初的類定義中添加幾行代碼,為這種靈活性提供基本結(jié)構(gòu)。
進(jìn)入對(duì)象初始化器(object initializer),這是不必在類中添加額外代碼(如此處詳細(xì)說明的構(gòu)造函數(shù))就可以實(shí) 例化和初始化對(duì)象的方式。實(shí)例化對(duì)象時(shí),要為每個(gè)需要初始化的、可公開訪問的屬性或字段使用名稱/值對(duì),來提供其值。其語法如下:
<ClassName> <variableName> = new <ClassName>
{
<propertyOrFieldl> = <valuel>,
<property0rField2> = <value2>,
...
<propertyOrFieldN> = <valueN>
};
例如,重寫前面的代碼,實(shí)例化和初始化一個(gè)Animal類型的對(duì)象,如下所示:
Animal animal = new Animal
{
Name = "Lea",
Age = 11,
Weight = 30.2
};
我們常可以把這樣的代碼放在一行上,而不會(huì)嚴(yán)重影響可讀性。
使用對(duì)象初始化器時(shí),不必顯式調(diào)用類的構(gòu)造函數(shù)。如果像上述代碼那樣省略構(gòu)造函數(shù)的括號(hào),就會(huì)自動(dòng)調(diào)用默認(rèn)的無參構(gòu)造函數(shù)。這是在初始化器設(shè)置參數(shù)值之前調(diào)用的,以便在需要時(shí)為默認(rèn)構(gòu)造函數(shù)中的參數(shù)提供默認(rèn)值。另外,可以調(diào)用特定的構(gòu)造函數(shù)。同樣,先調(diào)用這個(gè)構(gòu)造函數(shù),所以在構(gòu)造函數(shù)中對(duì)公共屬性進(jìn)行的初始化可能會(huì)被初始化器中提供的值覆蓋。只有能夠訪問所使用的構(gòu)造函數(shù)(如果沒有顯式指出,就是默認(rèn)的構(gòu)造函數(shù)),對(duì)象初始化器才能正常工作。
如果要用對(duì)象初始化器進(jìn)行初始化的屬性比本例中使用的簡單類型復(fù)雜,可以使用嵌套的對(duì)象初始化器, 即使用與前面相同的語法:
Animal animal = new Animal
{
Name = "Rual",
Age = "76",
Weight = 172.7,
Origin = new Farm
{
Name = "Circle Perk Ranch”,
Location = ’.Ann Road",
Rating = 15
}
};
這里初始化了一個(gè)Farm類型(這里沒有列出)的Origin屬性。代碼初始化了Origin屬性的3個(gè)特性:Name、Location和Rating,其值的類型分別是string、string和int。這個(gè)初始化操作使用了嵌套的對(duì)象初始化器。
注意,對(duì)象初始化器沒有替代非默認(rèn)的構(gòu)造函數(shù)。在實(shí)例化對(duì)象時(shí),可以使用對(duì)象初始化器來設(shè)置屬性和 字段值,但這并不意味著總是知道需要初始化什么狀態(tài)。通過構(gòu)造函數(shù),可以準(zhǔn)確地指定對(duì)象需要什么值才能起作用,再執(zhí)行代碼,以便立即響應(yīng)這些值。
另外,在上例中,使用嵌套的對(duì)象初始化器和使用構(gòu)造函數(shù)還有一個(gè)不太容易注意到的區(qū)別:對(duì)象的創(chuàng)建順序。使用嵌套的初始化器時(shí),首先創(chuàng)建頂級(jí)對(duì)象(Animal),然后創(chuàng)建嵌套對(duì)象(Farm),并把它賦值給屬性O(shè)rigin。如果使用構(gòu)造函數(shù),對(duì)象的創(chuàng)建順序就反了過來,而且要把Farm實(shí)例傳遞給Animal的構(gòu)造函數(shù)。在這個(gè)簡單例子中,使用這兩種方法的實(shí)際效果沒什么區(qū)別,但在某些情況下它們的區(qū)別可能十分明顯。
點(diǎn)擊加載更多評(píng)論>>