http://huan-lin.blogspot.com/2009/01/anonymous-types.html
有時候,例如在某個函式裡面,我們會臨時需要一個簡單的類別來儲存一些簡單資料,但又不想為了這個簡單的需求另外定義一個類別,此時便可使用 C# 的匿名型別(anonymous type)。
參考以下範例:
private void Foo() { var emp = new { Name = "Michael", Birthday = new DateTime(1971, 1, 1) }; Console.WriteLine("Employee name: " + emp.Name); Console.WriteLine("Birthday: " + emp.Birthday.ToString()); Console.WriteLine("實際的型別是: " + emp.GetType()); }這個範例使用了 隱含型別 var 來宣告區域變數 emp,這是必須的,因為我們使用了匿名型別。這表示從 new 運算子之後的大括弧包住的部分,會由編譯器產生一個類別定義。當然該類別的名稱也是由編譯器決定,所以我們在寫程式時便無法得知實際的類別名稱,自然就得用 var 來宣告變數了。
Employee name: Michael Birthday: 1971/1/1 上午 12:00:00 實際的型別是: <>f__AnonymousType0`2[System.String,System.DateTime]範例程式的最後一行是把匿名型別的實際型別名稱秀出來。注意此型別是個泛型類別(generic class),它有兩個參數型別。
private void Foo() { var emp1 = new { Name = "Michael", Birthday = new DateTime(1971, 1, 1) }; var emp2 = new { Name = "John", Birthday = new DateTime(1981, 12, 31) }; Console.WriteLine("emp1 的實際型別是: " + emp1.GetType()); Console.WriteLine("emp2 的實際型別是: " + emp2.GetType()); }
var emp2 = new { Name = "John", Birth = new DateTime(1981, 12, 31) };由於參數名稱不同,編譯器會產生另一個泛型類別。執行結果如下:
public class EmpInfo { private string name; private DateTime birthday; public EmpInfo(string aName, DateTime aBirthday) { name = aName; birthday = aBirthday; } public string Name { get { return name; } set { name = value; } } public DateTime Birthday { get { return birthday; } set { birthday = value; } } } class Program { static void Main(string[] args) { Console.WriteLine("示範 projection initializers 的匿名型別寫法。"); EmpInfo emp = new EmpInfo("Michael", new DateTime(1971, 1, 1)); var emp1 = new { emp.Name, emp.Birthday }; string name = "John"; int age = 20; var emp2 = new { name, age }; Console.WriteLine("emp1.Name = " + emp1.Name); Console.WriteLine("emp2.name = " + emp2.name); Console.WriteLine("emp1 的實際型別: " + emp1.GetType()); Console.WriteLine("emp2 的實際型別: " + emp2.GetType()); } }此範例包含兩種 projection initializer 的寫法,一種是利用事先定義的類別 EmpInfo 的屬性名稱,也就是說,編譯器在產生泛型類別時,會用 EmpInfo 的屬性名稱來當作參數名稱。另一種則是直接帶入區域變數名稱,即範例中以英文小寫宣告的變數 name 和 age。