C# 匿名類型的使用小結(jié)
匿名類型提供了一種快捷方式,將一組只讀屬性封裝到單個對象中,無需先顯式定義命名類型。類型名稱由編譯器在編譯時生成,源代碼中無法直接訪問。
- 聲明與推斷:一行代碼創(chuàng)建數(shù)據(jù)容器
- LINQ 投影:匿名類型的主要陣地
- 值相等性:相同屬性自動相等
- 匿名類型 vs 元組:什么時候選哪個
一、基本聲明
使用 new 運算符與對象初始值設(shè)定項結(jié)合來創(chuàng)建。
var person = new { Name = "Alice", Age = 30 };
Console.WriteLine($"{person.Name} is {person.Age} years old.");
// 輸出:Alice is 30 years old.
推斷的屬性名稱
當(dāng)使用變量或成員訪問表達式初始化時,編譯器自動推斷屬性名稱:
string productName = "Laptop";
decimal price = 999.99m;
var product = new { productName, price };
Console.WriteLine($"{product.productName}: {product.price:C}");
// 輸出:Laptop: $999.99
代碼解析: 不需要寫 Name = productName——編譯器從變量名推斷屬性名為 productName。
必須使用var
由于類型名稱不可見,必須使用 var 來聲明:
var person = new { Name = "Alice", Age = 30 };
// 不能寫成:AnonymousType person = ... // 類型名不存在
二、在 LINQ 查詢中使用
匿名類型最常見的用途是 LINQ 的 select 子句中的投影——只提取需要的屬性子集。
var words = new[] { "apple", "blueberry", "cherry" };
var results = words.Select(w => new { Word = w, Length = w.Length });
foreach (var item in results)
Console.WriteLine($"{item.Word} has {item.Length} letters.");
// 輸出:
// apple has 5 letters.
// blueberry has 9 letters.
// cherry has 6 letters.
劃重點: 這是匿名類型的核心場景。你不需要為每個查詢結(jié)果定義一個 DTO 類——一行代碼搞定。
三、相等性
具有相同屬性名稱和類型的兩個匿名類型實例會共享編譯器生成的同一類型。編譯器自動重寫 Equals 和 GetHashCode,基于屬性值比較:
var a = new { Name = "Alice", Age = 30 };
var b = new { Name = "Alice", Age = 30 };
var c = new { Name = "Bob", Age = 25 };
Console.WriteLine(a.Equals(b)); // True —— 相同類型、相同值
Console.WriteLine(a.Equals(c)); // False —— 值不同
注意: 屬性名稱相同但順序不同的匿名類型被視為不同類型——編譯器按照屬性名和順序生成類型。
四、嵌套匿名類型
匿名類型可以包含其他匿名類型:
var order = new
{
OrderId = 1,
Customer = new { Name = "Alice", City = "Seattle" },
Total = 150.00m
};
Console.WriteLine($"Order {order.OrderId} for {order.Customer.Name} in {order.Customer.City}");
// 輸出:Order 1 for Alice in Seattle
五、特性總結(jié)
| 特性 | 值 |
|---|---|
| 編譯器生成類型 | internal sealed class,派生自 Object |
| 屬性可訪問性 | 所有屬性 public 且只讀 |
| 支持的結(jié)構(gòu) | with 表達式、基于值的 Equals/GetHashCode/ToString |
| 表達式樹 | ? 支持(元組不支持) |
局限性
- 不能作為方法返回類型、方法參數(shù)或字段類型(無法命名)
- 作用域限定在聲明它們的方法內(nèi)
- 不能添加方法、事件或自定義運算符
- 屬性始終只讀
六、匿名類型 vs 元組
| 維度 | 匿名類型 | 元組 |
|---|---|---|
| 類型類別 | 引用類型 | 值類型 |
| 作用域 | 方法內(nèi) | 可跨方法 |
| 表達式樹 | ? 支持 | ? 不支持 |
| 解構(gòu) | ? | ? |
| 屬性可寫性 | 只讀 | 可讀寫(默認) |
| 語法簡潔度 | new { ... } | (...) |
| 推薦場景 | LINQ to SQL / 表達式樹 | 新代碼的通用數(shù)據(jù)分組 |
決策建議: 對于大多數(shù)新代碼,優(yōu)先使用元組——性能更好、語法更簡潔、支持解構(gòu)。只在與表達式樹(Entity Framework 的 Select 投影、動態(tài) LINQ 查詢)打交道時,匿名類型仍是不可替代的。
最后
匿名類型像是一個"方法內(nèi)部的 DTO"。在 LINQ 查詢中投影中間結(jié)果時非常方便,但一出了方法邊界就無能為力。新代碼中元組已經(jīng)替代了匿名類型的大部分場景,把它當(dāng)作 LINQ 投影的專用工具就好。
到此這篇關(guān)于C# 匿名類型的使用小結(jié)的文章就介紹到這了,更多相關(guān)C# 匿名類型內(nèi)容請搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
C#用Topshelf創(chuàng)建Windows服務(wù)的步驟分享
這篇文章主要給大家介紹了關(guān)于C#如何利用Topshelf創(chuàng)建Windows服務(wù)的相關(guān)資料,文中通過示例代碼介紹的非常詳細,對大家學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價值,需要的朋友們下面來一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05

