C# 匿名類型的使用小結(jié)
匿名類型提供了一種快捷方式,將一組只讀屬性封裝到單個(gè)對(duì)象中,無(wú)需先顯式定義命名類型。類型名稱由編譯器在編譯時(shí)生成,源代碼中無(wú)法直接訪問(wèn)。
- 聲明與推斷:一行代碼創(chuàng)建數(shù)據(jù)容器
- LINQ 投影:匿名類型的主要陣地
- 值相等性:相同屬性自動(dòng)相等
- 匿名類型 vs 元組:什么時(shí)候選哪個(gè)
一、基本聲明
使用 new 運(yùn)算符與對(duì)象初始值設(shè)定項(xiàng)結(jié)合來(lái)創(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)使用變量或成員訪問(wèn)表達(dá)式初始化時(shí),編譯器自動(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 來(lái)聲明:
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.
劃重點(diǎn): 這是匿名類型的核心場(chǎng)景。你不需要為每個(gè)查詢結(jié)果定義一個(gè) DTO 類——一行代碼搞定。
三、相等性
具有相同屬性名稱和類型的兩個(gè)匿名類型實(shí)例會(huì)共享編譯器生成的同一類型。編譯器自動(dòng)重寫 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 |
| 屬性可訪問(wèn)性 | 所有屬性 public 且只讀 |
| 支持的結(jié)構(gòu) | with 表達(dá)式、基于值的 Equals/GetHashCode/ToString |
| 表達(dá)式樹 | ? 支持(元組不支持) |
局限性
- 不能作為方法返回類型、方法參數(shù)或字段類型(無(wú)法命名)
- 作用域限定在聲明它們的方法內(nèi)
- 不能添加方法、事件或自定義運(yùn)算符
- 屬性始終只讀
六、匿名類型 vs 元組
| 維度 | 匿名類型 | 元組 |
|---|---|---|
| 類型類別 | 引用類型 | 值類型 |
| 作用域 | 方法內(nèi) | 可跨方法 |
| 表達(dá)式樹 | ? 支持 | ? 不支持 |
| 解構(gòu) | ? | ? |
| 屬性可寫性 | 只讀 | 可讀寫(默認(rèn)) |
| 語(yǔ)法簡(jiǎn)潔度 | new { ... } | (...) |
| 推薦場(chǎng)景 | LINQ to SQL / 表達(dá)式樹 | 新代碼的通用數(shù)據(jù)分組 |
決策建議: 對(duì)于大多數(shù)新代碼,優(yōu)先使用元組——性能更好、語(yǔ)法更簡(jiǎn)潔、支持解構(gòu)。只在與表達(dá)式樹(Entity Framework 的 Select 投影、動(dòng)態(tài) LINQ 查詢)打交道時(shí),匿名類型仍是不可替代的。
最后
匿名類型像是一個(gè)"方法內(nèi)部的 DTO"。在 LINQ 查詢中投影中間結(jié)果時(shí)非常方便,但一出了方法邊界就無(wú)能為力。新代碼中元組已經(jīng)替代了匿名類型的大部分場(chǎng)景,把它當(dāng)作 LINQ 投影的專用工具就好。
到此這篇關(guān)于C# 匿名類型的使用小結(jié)的文章就介紹到這了,更多相關(guān)C# 匿名類型內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
Unity shader實(shí)現(xiàn)自由放大縮小效果
這篇文章主要為大家詳細(xì)介紹了Unity shader實(shí)現(xiàn)自由放大縮小效果,具有一定的參考價(jià)值,感興趣的小伙伴們可以參考一下2019-02-02
C#用Topshelf創(chuàng)建Windows服務(wù)的步驟分享
這篇文章主要給大家介紹了關(guān)于C#如何利用Topshelf創(chuàng)建Windows服務(wù)的相關(guān)資料,文中通過(guò)示例代碼介紹的非常詳細(xì),對(duì)大家學(xué)習(xí)或者使用C#具有一定的參考學(xué)習(xí)價(jià)值,需要的朋友們下面來(lái)一起學(xué)習(xí)學(xué)習(xí)吧2020-05-05

