深入理解C# 3.x的新特性系列自開篇以後,已經有兩個月了。在前面的章節中,我們先後深入討論了C# 3.x新引入的一些列新特性:Anomynous Type、Extension Method、Lambda Expression、Automatically Implemented Property,今天我們來討論本系列的涉及的另外兩個簡單的Feature: Object Initializer 和 Collection Initializer。
一、 為什麼要引入Object Initializer 和 Collection Initializer
在建立一個具有較多屬性的對象時,我們一定經常遇到這樣的狀況:為了盡量地使我們的Code更加簡潔,我們試圖調用一個適合的Constructor使得對象在建立過程中就可以為所需的屬性進行初始化,但是往往我們找不到這樣“完美”的Constructor都能夠匹配我們需要進行初始化的屬性列表。於是我們通常調用一個相對適合的Constructor建立我們需要的對象,對於沒能在Constructor中初始化的Field或者Property,再一次對其進行賦值。現在我們有了一個好的辦法有效地解決了這個問題,那就是Object Initializer。
上面說的對於一個一般對象的建立和初始化,現在說說我們經常使用的實現了介面System.Collections.IEnumerable的Collection的建立和初始化。對於這樣的對象,我們一般先通過Constructor建立該對象,然後通過Add方法或者其他的方式將添加我們所需Element。現在我們可以通過Collection Initializer將這個兩個過程合二為一。
接下來我們就來介紹如果使用Object Initializer和Collection Initializer,以及他們背後的本質是什麼:Compiler到底在編譯的時候為我們做的什麼。
二、 Object Initializer的使用和本質
Object Initializer的使用很簡單:在通過new 關鍵字建立對象的時候,將所需的Field/Proeprty的複製置於Type name後的{}中。比如:
class Program
{
static void Main(string[] args)
{
Vector v = new Vector { X = 1, Y = 2 };
}
}
class Vector
{
public double X
{
get;
set;
}
public double Y
{
get;
set;
}
}
註:對於Vector的定義,還使用到了C#3.x的另一個新的特性:Automatically Implemented Proeprty。
在上面的例子中,我們通過一句代碼(Vector v = new Vector { X = 1, Y = 2 }; )實現對Vector對象的建立和對X&Y的初始化。
在本系列開始的時候,我就一直在強調: C# 3.x這些Feature僅僅是基於一種Programming Language層面的新特性而已,這些特性通過Programming Language對應的Compiler在編譯過程添加一些輔助的Code來實現。對於上面這句簡單的Code(Vector v = new Vector { X = 1, Y = 2 }; ),通過編譯,將會下面這個樣子:
Vector <>g__initLocal0 = new Vector();
<>g__initLocal0.X = 1;
<>g__initLocal0.Y = 2;
Vector v = <>g__initLocal0;
通過對上面一段代碼的分析,我們可以歸納出Compiler通過以下3個步驟實現Object Initializer。
- 調用對應Class的對應的Constructor建立一個臨時對象。
- 根據在{}的指派陳述式對臨時對象對應的Field/Property進行賦值。
- 將這個臨時對象賦值給你建立的對象。
三、 Collection Initializer的使用與本質
Collection Initializer將Collection對象的建立和對於Element的初始化合二為一,他的使用和Object Initializer很類似:將Element List直接加個Class name後的{}中:
IList<string> list = new List<string> { "Zhang San", "Li Si", "Wang Wu" };
和分析Object Initializer的本質一樣,我們之後看看通過Compiler變異後的Code是什麼樣子,就會對Collection Initializer的實現有一個全面的瞭解:
List<string> <>g__initLocal0 = new List<string>();
<>g__initLocal0.Add("Zhang San");
<>g__initLocal0.Add("Li Si");
<>g__initLocal0.Add("Wang Wu");
IList<string> list = <>g__initLocal0;
Collection Initializer的實現和Object Initializer很類似:
- 調用對應Class的Default Constructor(無參的)建立一個臨時對象。
- 根據在{}的指派陳述式,通過調用Add方法添加相應的Element。
- 將這個臨時對象賦值給你建立的對象。
C# 3.x相關內容:
[原創]深入理解C# 3.x的新特性(1):Anonymous Type
[原創]深入理解C# 3.x的新特性(2):Extension Method - Part I
[原創]深入理解C# 3.x的新特性(2):Extension Method - Part II
[原創]深入理解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression
[原創]深入理解C# 3.x的新特性(4):Automatically Implemented Property
[原創]深入理解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer