匿名型態提供了一種方便的方式,可以將一組唯讀屬性封裝在單一物件中,而無需先定義命名型別。 編譯器會在編譯時產生一個型別名稱,而你無法在原始碼中存取。 編譯器會推斷每個屬性的類型。
透過使用 new 運算子與物件初始化器來建立匿名型別。 以下範例展示了一個以兩個屬性 Name 和 Age 初始化的匿名型別。
var person = new { Name = "Alice", Age = 30 };
Console.WriteLine($"{person.Name} is {person.Age} years old.");
// Output:
// Alice is 30 years old.
推斷屬性名稱
你可以透過語 Name = value 法明確指定屬性名稱。 當你初始化一個匿名型別時,使用變數或成員存取表達式,編譯器會從該表達式推斷出屬性名稱:
string productName = "Laptop";
decimal price = 999.99m;
var product = new { productName, price };
Console.WriteLine($"{product.productName}: {product.price:C}");
// Output:
// Laptop: $999.99
在前述範例中,編譯器從初始化器中使用的變數名稱推斷屬性名稱 productName 和 price。
宣告使用 var 的匿名型別
因為編譯器會產生型別名稱,而你無法存取原始碼中的類型名稱,所以你必須用 來 var 宣告本地變數。 你不能明確指定類型名稱:
// You must use var — you can't write a named type here.
var person = new { Name = "Alice", Age = 30 };
在 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.");
}
// Output:
// apple has 5 letters.
// blueberry has 9 letters.
// cherry has 6 letters.
平等
兩個擁有相同屬性名稱與類型且順序相同的匿名型態實例,會共享相同的編譯器產生型別。 編譯器會覆寫 `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}");
// Output:
// Order 1 for Alice in Seattle
特性
匿名型具有以下特徵:
- 編譯器會將它們生成為從 Object 衍生出來的
internal sealed class類型。 - 所有屬性皆為
public且唯讀。 - 匿名型態支持
with非破壞性突變的表達式。 - 編譯器會針對Equals、GetHashCode 及ToString產生值型覆寫。
- 匿名型態支援 表達樹,而元組則不支援。
局限性
匿名型態有幾個限制:
- 你不能把它們當作方法的回傳類型、方法參數或欄位類型,因為你無法命名類型。
- 它們的範圍是根據你宣告的方式來設定的。
- 你無法新增方法、事件或自訂運算子。
- 屬性總是唯讀;匿名類型不支援可變屬性。
何時該改用元組
對於大多數新程式碼,建議使用 元組 取代匿名型別。 作為值類型,元組能提供更好的效能。 它們也提供解構支援和更靈活的語法。 當你需要表達式樹支援或參考型語意時,匿名型態仍然是更好的選擇。 詳細比較請參見「 匿名型別與元組型別的選擇」。