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