程序師世界是廣大編程愛好者互助、分享、學習的平台,程序師世界有你更精彩!
首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫知識
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
 程式師世界 >> 編程語言 >> .NET網頁編程 >> C# >> 關於C# >> C# 3.0特性 - 對象集合初始化器

C# 3.0特性 - 對象集合初始化器

編輯:關於C#

在寫一些實體類的時候,我們往往在寫構造方法的時候思考很長時間,除了 一個無參構造器外還在想需要寫幾個構造器呢?哪些參數是需要初始化的。現在 你再也不需要為這事煩惱了。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反編譯程序集:

Book <>g__initLocal0 = new Book();
<>g__initLocal0.Title = "Inside COM";
<>g__initLocal0.ISBN = "123-456-789";
Book book = <>g__initLocal0;

C#編譯器生成了一個新的 局部變量<>g__initLocal0,調用Book的默認無參構造方法初始化它,然 後對它的屬性進行賦值,最後將這個局部變量賦值給book。看到這裡,我們應該 想到,要使用對象初始化器,那麼這個對象必須有一個無參構造方法,如果你給 這個方法寫了一個有參構造方法而將它的默認無參構造方法覆蓋了並且沒有提供 一個新的無參構造方法,那麼使用對象初始化器編譯的時候是不會通過的(不過 想不通,為啥C#編譯器生成這麼一個奇怪的局部變量名字,還有為啥不直接使用 book呢)。像下面的代碼不更好:

Book book = new Book();
book.Title = "Inside COM";
book.ISBN = "123-456-789";

後來我發現我是在debug模式下編譯的,換到release 模式下變成了這樣:

Book <>g__initLocal0 = new Book();
<>g__initLocal0.Title = "Inside COM";
<>g__initLocal0.ISBN = "123-456-789";

被 優化了。上面介紹的就是對象初始化器了,那什麼是集合初始化器呢?

IList<Book> books = new List<Book>();
//這裡就使用了對象初始化器,學以致用吧
books.Add(new Book { Title = "Inside COM", ISBN = "123-456-789",Price=20 });
books.Add(new Book { Title = "Inside C#", ISBN = "123-356-d89",Price=100 });
books.Add(new Book { Title = "Linq", ISBN = "123-d56-d89", Price = 120 });

這樣的代碼沒少寫吧,實際上也許比這 更復雜,有了C# 3.0我們睡覺都想笑:

IList<Book> books = new List<Book> {
new Book { Title = "Inside COM", ISBN = "123-456-789",Price=20 },
new Book { Title = "Inside C#", ISBN = "123-356-d89",Price=100 },
new Book { Title = "Linq", ISBN = "123-d56-d89", Price = 120 }
};

還是像剛才一樣,我們來欣賞一下C#編譯器為我們生成的代 碼:

List<Book> <>g__initLocal0 = new List<Book>();
Book <>g__initLocal1 = new Book();
<>g__initLocal1.Title = "Inside COM";
<>g__initLocal1.ISBN = "123-456-789";
<>g__initLocal1.Price = 20f;
<>g__initLocal0.Add(<>g__initLocal1);
Book <>g__initLocal2 = new Book();
<>g__initLocal2.Title = "Inside C#";
<>g__initLocal2.ISBN = "123-356-d89";
<>g__initLocal2.Price = 100f;
<>g__initLocal0.Add(<>g__initLocal2);
Book <>g__initLocal3 = new Book();
<>g__initLocal3.Title = "Linq";
<>g__initLocal3.ISBN = "123-d56-d89";
<>g__initLocal3.Price = 120f;
<>g__initLocal0.Add(<>g__initLocal3);

從上面的代碼來看,編譯器自動的調 用了List的無參構造方法,然後實例化一個個的Book,再一個個的Add進去,和 我們原來的做法沒有什麼不同,但是,這是編譯器為我們做的,所以簡省了我們 很多的編碼工作。

對象集合初始化器就算介紹完了。有人也許會說,不 就是個syntx sugar麼,有什麼。是的,確實是個語法糖。在編譯器發展早期,編譯器科學家門一直在想方設法的優化編譯器生成的代碼,這個時候,編譯器做 的主要是對機器優化,因為那個時候機器的時間非常寶貴,機器運算速度也不快 ,今天我們有了足夠好的機器了(但並不是說我們可以不關注性能的編寫程序),而且作為編寫軟件的人來說,比機器的時間寶貴得多,所以今天的編譯器也在向 人優化了,從編程語言的發展之路來講,今天的編程語言比昨天的語言更高級,也更人性化了,我們只要編寫更少的代碼,更符合人的思維的代碼,而只要關注 我們值的關注的地方。體力活兒就交給編譯器吧。

附加:

剛 開始想想這對象集合初始化器也許就一雞肋,沒啥用,不就減少一點點代碼麼,像這種簡單的初始化工作,大部分代碼生成器都可以來干。後來在研究匿名類型 的時候突然發現,如果沒有這個對象初始化器,匿名類型是不是要復雜一些?或 者就是難以實現?

var test = new {Key="test",Value="test"};如果沒有對象初始化器,匿 名類型該怎麼辦?

  1. 上一頁:
  2. 下一頁:
Copyright © 程式師世界 All Rights Reserved