天天看點

深入了解C# 3.x的新特性(5):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後的{}中。比如:

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

class Program

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

    {

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

        static void Main(string[] args)

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

        {

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

            Vector v = new Vector { X = 1, Y = 2 };            

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

        }

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

    }

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer
深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

    class Vector

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer
深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

        public double X

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer
深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

            get;

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

            set;

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer
深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer
深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

        public double Y

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer
深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer
深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer
深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer
深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

}

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

在上面的例子中,我們通過一句代碼(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 }; ),通過編譯,将會下面這個樣子:

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

Vector <>g__initLocal0 = new Vector();

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

<>g__initLocal0.X = 1;

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

<>g__initLocal0.Y = 2;

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

Vector v = <>g__initLocal0;

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

通過對上面一段代碼的分析,我們可以歸納出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的實作有一個全面的了解:

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

List<string> <>g__initLocal0 = new List<string>();

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

<>g__initLocal0.Add("Zhang San");

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

<>g__initLocal0.Add("Li Si");

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

<>g__initLocal0.Add("Wang Wu");

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

IList<string> list = <>g__initLocal0;

深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer

Collection Initializer的實作和Object Initializer很類似:       

調用對應Class的Default Constructor(無參的)建立一個臨時對象。

根據在{}的指派語句,通過調用Add方法添加相應的Element。

将這個臨時對象指派給你建立的對象。

C# 3.x相關内容:

<a target="_blank" href="http://www.cnblogs.com/artech/archive/2007/07/15/818980.html">[原創]深入了解C# 3.x的新特性(1):Anonymous Type</a>

<a target="_blank" href="http://www.cnblogs.com/artech/archive/2007/07/18/821881.html">[原創]深入了解C# 3.x的新特性(2):Extension Method - Part I</a>

<a target="_blank" href="http://www.cnblogs.com/artech/archive/2007/07/19/823847.html">[原創]深入了解C# 3.x的新特性(2):Extension Method - Part II</a>

<a target="_blank" href="http://www.cnblogs.com/artech/archive/2007/08/22/865247.html">[原創]深入了解C# 3.x的新特性(3):從Delegate、Anonymous Method到Lambda Expression</a>

<a target="_blank" href="http://www.cnblogs.com/artech/archive/2007/09/30/912166.html">[原創]深入了解C# 3.x的新特性(5):Object Initializer 和 Collection Initializer</a>

作者:蔣金楠

微信公衆賬号:大内老A

如果你想及時得到個人撰寫文章以及著作的消息推送,或者想看看個人推薦的技術資料,可以掃描左邊二維碼(或者長按識别二維碼)關注個人公衆号(原來公衆帳号蔣金楠的自媒體将會停用)。

本文版權歸作者和部落格園共有,歡迎轉載,但未經作者同意必須保留此段聲明,且在文章頁面明顯位置給出原文連接配接,否則保留追究法律責任的權利。

<a href="http://www.cnblogs.com/artech/archive/2007/09/30/912166.html" target="_blank">原文連結</a>