共用方式為


匿名類型(C# 程式設計指南)

匿名型態提供了一種方便的方式,可以將一組唯讀屬性封裝在單一物件中,而無需先定義命名型別。 編譯器會在編譯時產生一個型別名稱,而你無法在原始碼中存取。 編譯器會推斷每個屬性的類型。

透過使用 new 運算子與物件初始化器來建立匿名型別。 以下範例展示了一個以兩個屬性 NameAge 初始化的匿名型別。

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

在前述範例中,編譯器從初始化器中使用的變數名稱推斷屬性名稱 productNameprice

宣告使用 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非破壞性突變的表達式。
  • 編譯器會針對EqualsGetHashCodeToString產生值型覆寫。
  • 匿名型態支援 表達樹,而元組則不支援。

局限性

匿名型態有幾個限制:

  • 你不能把它們當作方法的回傳類型、方法參數或欄位類型,因為你無法命名類型。
  • 它們的範圍是根據你宣告的方式來設定的。
  • 你無法新增方法、事件或自訂運算子。
  • 屬性總是唯讀;匿名類型不支援可變屬性。

何時該改用元組

對於大多數新程式碼,建議使用 元組 取代匿名型別。 作為值類型,元組能提供更好的效能。 它們也提供解構支援和更靈活的語法。 當你需要表達式樹支援或參考型語意時,匿名型態仍然是更好的選擇。 詳細比較請參見「 匿名型別與元組型別的選擇」。

另請參閱