在 C# 3.0 之前,建立物件並設定屬性通常需要多行程式碼:
Staff s = new Staff();
s.Name = "GUOJUN";
s.Age = 27;
物件初始化器讓我們能在單一陳述式中完成建立與初始化,這在 LINQ 查詢投射新物件時尤為重要,避免查詢表達式變得冗長難讀。
在 new 建構函式呼叫後,直接接著大括號 {} 設定屬性:
// 類別定義
class Staff
{
public string Name { get; set; }
public int Age { get; set; }
public string Add;
public Staff() { }
public Staff(int i, string s) { Name = s; Age = i; }
}
// 使用物件初始化器
Console.WriteLine("Initializer");
Staff s1 = new Staff(12, "sss") { Name = "GUOJUN" };
Staff s3 = new Staff(12, "sss") { Name = "GUOJUN", Age = 27, Add = "HuBei" };
Staff s2 = new Staff { Name = "IORI", Age = 27 };
s2 使用無參數建構函式。s1、s3 使用帶參數建構函式,其後仍可設定屬性。C# 3.0 的新特性純屬語言層面,透過編譯器在編譯期注入輔助程式碼實現。反編譯觀察:
public static void fnInitializer()
{
Console.WriteLine("Initializer");
Staff <>g__initLocal3 = new Staff(12, "sss");
<>g__initLocal3.Name = "GUOJUN";
Staff s1 = <>g__initLocal3;
Staff <>g__initLocal4 = new Staff(12, "sss");
<>g__initLocal4.Name = "GUOJUN";
<>g__initLocal4.Age = 0x1b;
<>g__initLocal4.Add = "HuBei";
Staff s3 = <>g__initLocal4;
Staff <&>g__initLocal5 = new Staff();
<&>g__initLocal5.Name = "IORI";
<&>g__initLocal5.Age = 0x1b;
Staff s2 = <&>g__initLocal5;
Console.WriteLine(s1.Name);
Console.WriteLine(s1.Age);
Console.WriteLine(s2.Name);
}
編譯器自動產生暫存變數(<&>g__initLocalX),先建立物件、再設定屬性、最後指派給目標變數。執行期行為與手寫展開版本完全一致,無額外效能負擔。