二、匿名類型
在第一篇中,給了簡單的匿名類型的例子,這裡再詳細說。
匿名類型提供了一種方便的方法,可用來將一組只讀屬性封裝到單個對象中,而無需首先顯式定義一個類型。
類型名由編譯器生成,並且不能在源代碼級使用。
這些屬性的類型由編譯器推斷。如:
匿名類型通常用在查詢表達式的select子句中,以便返回源序列中每個對象的屬性子集。
匿名類型是使用new 運算符和對象初始值設定項(初始化器)創建的。
匿名類型是由一個或多個公共只讀屬性組成的類類型。不允許包含其他種類的類成員(如方法或事件)。如:
var noname = new { name = "yyao", age = 24 };//匿名類型
也就是說,匿名類型由編譯器來推斷出一個嚴格的類型,編譯器是可以對其類型進行判定的,只是其類型的名字不由編程者所知而已。如,有如下定義:
var noname = new { namea = "yyao", age = 24 };//匿名類型
var qname = new { namea = "selfcherish", age = 25 };
var gname = new { username = "selfcherish", age = 25 };
qname = noname;
gname = qname;
這三個定義,第一個賦值沒有任何問題,說明編譯器自動判斷了它們兩者的類型是相同的,從而可以賦值。而第二個賦值,則報錯:Cannot implicitly convert type 'AnonymousType#1' to 'AnonymousType#2'。定義匿名類型的時候,還需要注意,不能用null賦初值。如:
var vara = new { hei = null, id = 5 };
將報錯:Cannot assign <null> to anonymous type property。另外,匿名類型是由一個或多個只讀屬性組成的類類型,如,gname可以通過gname.username和gname.age來訪問,但是想通過:
gname.age = 26;
則報錯:Property or indexer 'AnonymousType#1.age' cannot be assigned to -- it is read only。
匿名類型,最常見的使用方式是用其他類型的一些屬性初始化匿名類型:
MyClass[] ojbset = new MyClass[12];
var vaobj =
from obj in ojbset
select new { obj.Name, obj.Number };
foreach (var v in vaobj)
{
Console.WriteLine("Name={0}, Number={1}", v.Name, v.Number);
}
這裡的MyClass可能不只兩個屬性,只選了Name和Number這兩個屬性來初始化vaobj。另外,在將匿名類型分配給變量時,必須使用var構造初始化該變量,因為匿名類型不能用某類型來定義,只能用var,也就是說,只有編譯器能夠訪問匿名類型的基礎名稱,編譯器通過var來訪問匿名類型的基礎變量vaobj。