C# 3.0為你提供了對象集合初始化器:
/// <summary>/// 圖書類/// </summary>public class Book{ /// <summary> /// 圖書名稱 /// </summary> public string Title { get; set; } /// <summary> /// 單價 /// </summary> public float Price { get; set; } /// <summary> /// 作者 /// </summary> public string Author { get; set; } /// <summary> /// ISBN號 /// </summary> public string ISBN { get; set; }}//對象初始化器Book book = new Book { Title="Inside COM",ISBN="123-456-789"};
現在你想初始化幾個就初始化幾個,不需要出現這種情況:
public Book():this(""){ }public Book(string title):this(title,0){}public Book(string title, float price):this(title,price,""){ }public Book(string title, float price, string isbn){ this.Title = title; this.Price = price; this.ISBN = isbn;}
這一串的構造方法都是為了應付不同的初始化情況。
好了,來看看對象初始化器編譯器在后面為我們做了些什么呢?
使用Reflector反編譯程序集:
C#編譯器生成了一個新的局部變量<>g__initLocal0,調用Book的默認無參構造方法初始化它,然后對它的屬性進行賦值,最后將這個局部變量賦值給book。看到這里,我們應該想到,要使用對象初始化器,那么這個對象必須有一個無參構造方法,如果你給這個方法寫了一個有參構造方法而將它的默認無參構造方法覆蓋了并且沒有提供一個新的無參構造方法,那么使用對象初始化器編譯的時候是不會通過的(不過想不通,為啥C#編譯器生成這么一個奇怪的局部變量名字,還有為啥不直接使用book呢)。像下面的代碼不更好:
后來我發現我是在debug模式下編譯的,換到release模式下變成了這樣:
被優化了。上面介紹的就是對象初始化器了,那什么是集合初始化器呢?
這樣的代碼沒少寫吧,實際上也許比這更復雜,有了C# 3.0我們睡覺都想笑:
還是像剛才一樣,我們來欣賞一下C#編譯器為我們生成的代碼:
從上面的代碼來看,編譯器自動的調用了List的無參構造方法,然后實例化一個個的Book,再一個個的Add進去,和我們原來的做法沒有什么不同,但是,這是編譯器為我們做的,所以簡省了我們很多的編碼工作。
對象集合初始化器就算介紹完了。有人也許會說,不就是個syntx sugar么,有什么。是的,確實是個語法糖。在編譯器發展早期,編譯器科學家門一直在想方設法的優化編譯器生成的代碼,這個時候,編譯器做的主要是對機器優化,因為那個時候機器的時間非常寶貴,機器運算速度也不快,今天我們有了足夠好的機器了(但并不是說我們可以不關注性能的編寫程序),而且作為編寫軟件的人來說,比機器的時間寶貴得多,所以今天的編譯器也在向人優化了,從編程語言的發展之路來講,今天的編程語言比昨天的語言更高級,也更人性化了,我們只要編寫更少的代碼,更符合人的思維的代碼,而只要關注我們值的關注的地方。體力活兒就交給編譯器吧。
附加:
剛開始想想這對象集合初始化器也許就一雞肋,沒啥用,不就減少一點點代碼么,像這種簡單的初始化工作,大部分代碼生成器都可以來干。后來在研究匿名類型的時候突然發現,如果沒有這個對象初始化器,匿名類型是不是要復雜一些?或者就是難以實現?
var test = new{Key="test",Value="test"};如果沒有對象初始化器,匿名類型該怎么辦?
新聞熱點
疑難解答