Linq匿名類型簡單概述
Linq有很多值得學習的地方,這里我們主要介紹Linq匿名類型,包括介紹使用Linq匿名類型的地方都策略性地省略了局部變量的類型等方面。
Linq匿名類型
如果我們想繼續使用我們現有的語法來返回名稱和地址,我們很快便會面臨問題,即不存在僅包含 Name 和 Address 的類型。雖然我們仍然可以編寫此查詢,但是必須引入該類型:
- class CustomerTuple
- {
- public string Name;
- public string Address;
- public CustomerTuple(string name, string address)
- {
- this.Name = name;
- this.Address = address;
- }
- }
然后我們才能使用該類型,即此處的 CustomerTuple,以生成我們查詢的結果。
- IEnumerable<CustomerTuple> locals = customers.Where(c => c.ZipCode == 91822).
Select(c => new CustomerTuple(c.Name, c.Address));
那確實像許多用于投影出字段子集的樣板代碼。而且還往往不清楚如何命名此種類型。 CustomerTuple 確實是個好名稱嗎?如果投影出 Name 和 Age 又該如何命名?那也可以叫做 CustomerTuple。因此,問題在于我們擁有樣板代碼,而且似乎無法為我們創建的類型找到任何恰當的名稱。此外,還可能需要許多不同的類型,如何管理這些類型很快便可能成為一個棘手的問題。
這正是Linq匿名類型要解決的問題。此功能主要允許在無需指定名稱的情況下創建結構化類型。如果我們使用Linq匿名類型重新編寫上述查詢,其代碼如下所示:
- locals = customers.Where(c => c.ZipCode == 91822).
Select(c => new { c.Name, c.Address });
此代碼會隱式創建一個具有 Name 和 Address 字段的類型:
- class
- {
- public string Name;
- public string Address;
- }
此類型不能通過名稱引用,因為它沒有名稱。創建Linq匿名類型時,可顯式聲明字段的名稱。例如,如果正在創建的字段派生于一條復雜的表達式,或純粹不需要名稱,就可以更改名稱:
- locals = customers.Where(c => c.ZipCode == 91822).Select(c => new {
FullName = c.FirstName + “ “ + c.LastName, HomeAddress = c.Address });
在此情形下,生成的類型具有名為 FullName 和 HomeAddress 的字段。
這樣我們又向理想世界前進了一步,但仍存在一個問題。您將發現,我在任何使用Linq匿名類型的地方都策略性地省略了局部變量的類型。顯然我們不能聲明Linq匿名類型的名稱,那我們如何使用它們?
【編輯推薦】