匿名類型 (C# 程式設計手冊)Anonymous Types (C# Programming Guide)

匿名類型提供一個便利的方法,將一組唯讀屬性封裝成一個物件,而不需要事先明確定義類型。Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to explicitly define a type first. 類型名稱會由編譯器產生,並且無法在原始程式碼層級使用。The type name is generated by the compiler and is not available at the source code level. 每個屬性的類型會由編譯器推斷。The type of each property is inferred by the compiler.

您可以搭配物件初始設定式使用 new 運算子,來建立匿名型別。You create anonymous types by using the new operator together with an object initializer. 如需物件初始設定式的詳細資訊,請參閱物件和集合初始設定式For more information about object initializers, see Object and Collection Initializers.

下列範例顯示以兩個名為 AmountMessage 的屬性初始化的匿名類型。The following example shows an anonymous type that is initialized with two properties named Amount and Message.

var v = new { Amount = 108, Message = "Hello" };  
  
// Rest the mouse pointer over v.Amount and v.Message in the following  
// statement to verify that their inferred types are int and string.  
Console.WriteLine(v.Amount + v.Message);  

您通常可以在查詢運算式的 select 子句中使用匿名型別,以從來源序列中的每個物件傳回屬性子集。Anonymous types typically are used in the select clause of a query expression to return a subset of the properties from each object in the source sequence. 如需查詢的詳細資訊,請參閱 LINQ 查詢運算式For more information about queries, see LINQ Query Expressions.

匿名類型包含一個或多個公用唯讀屬性。Anonymous types contain one or more public read-only properties. 其他類型的類別成員 (例如方法或事件) 則無效。No other kinds of class members, such as methods or events, are valid. 用於初始化屬性的運算式不可以是 null、匿名函式或指標類型。The expression that is used to initialize a property cannot be null, an anonymous function, or a pointer type.

最常見的情況是使用其他類型的屬性來初始化匿名類型。The most common scenario is to initialize an anonymous type with properties from another type. 下列範例假設存在一個名為 Product 的類別。In the following example, assume that a class exists that is named Product. Product 類別包含 ColorPrice 屬性,以及您不感興趣的其他屬性。Class Product includes Color and Price properties, together with other properties that you are not interested in. 變數 productsProduct 物件的集合。Variable products is a collection of Product objects. 匿名類型宣告的開頭為 new 關鍵字。The anonymous type declaration starts with the new keyword. 宣告會初始化新類型,只使用 Product 中的兩個屬性。The declaration initializes a new type that uses only two properties from Product. 這會使查詢中傳回較小的資料量。This causes a smaller amount of data to be returned in the query.

如果未在匿名類型中指定成員名稱,編譯器會為匿名類型成員指定與用於初始化類型之屬性相同的名稱。If you do not specify member names in the anonymous type, the compiler gives the anonymous type members the same name as the property being used to initialize them. 您必須為以運算式初始化的屬性提供一個名稱,如上述範例所示。You must provide a name for a property that is being initialized with an expression, as shown in the previous example. 在下列範例中,匿名類型的屬性名稱是 ColorPriceIn the following example, the names of the properties of the anonymous type are Color and Price.

var productQuery = 
    from prod in products
    select new { prod.Color, prod.Price };

foreach (var v in productQuery)
{
    Console.WriteLine("Color={0}, Price={1}", v.Color, v.Price);
}

一般而言,當您使用匿名型別初始化變數時,您可以使用 var 將變數宣告為隱含型別區域變數。Typically, when you use an anonymous type to initialize a variable, you declare the variable as an implicitly typed local variable by using var. 由於只有編譯器可以存取匿名類型的基本名稱,因此無法在變數宣告中指定類型名稱。The type name cannot be specified in the variable declaration because only the compiler has access to the underlying name of the anonymous type. 如需 var 的詳細資訊,請參閱隱含類型區域變數For more information about var, see Implicitly Typed Local Variables.

您可以如下列範例所示,合併隱含類型區域變數和隱含類型陣列,以建立匿名類型項目的陣列。You can create an array of anonymously typed elements by combining an implicitly typed local variable and an implicitly typed array, as shown in the following example.

var anonArray = new[] { new { name = "apple", diam = 4 }, new { name = "grape", diam = 1 }};  

備註Remarks

匿名型別是直接衍生自 object,並且無法轉換成 object 以外之任何類型的 class 類型。Anonymous types are class types that derive directly from object, and that cannot be cast to any type except object. 編譯器提供每種匿名類型的名稱,不過您的應用程式無法存取此名稱。The compiler provides a name for each anonymous type, although your application cannot access it. 對 Common Language Runtime 來說,匿名類型與其他任何參考類型並無不同。From the perspective of the common language runtime, an anonymous type is no different from any other reference type.

如果組件中有兩個或多個匿名物件初始設定式,指定了順序相同並具有相同名稱和類型的屬性序列,編譯器會將這些物件視為相同類型的執行個體。If two or more anonymous object initializers in an assembly specify a sequence of properties that are in the same order and that have the same names and types, the compiler treats the objects as instances of the same type. 這些物件會共用編譯器產生的相同類型資訊。They share the same compiler-generated type information.

您無法將欄位、屬性、事件或方法的傳回類型,宣告為具有匿名類型。You cannot declare a field, a property, an event, or the return type of a method as having an anonymous type. 同樣地,您無法將方法、屬性、建構函式或索引子的型式參數宣告為具有匿名類型。Similarly, you cannot declare a formal parameter of a method, property, constructor, or indexer as having an anonymous type. 若要以方法引數的形式來傳遞匿名類型或含有匿名類型的集合,您可以將參數宣告為 object 類型。To pass an anonymous type, or a collection that contains anonymous types, as an argument to a method, you can declare the parameter as type object. 但是,這樣做將失去強式類型的目的。However, doing this defeats the purpose of strong typing. 如果您必須在方法界限外儲存或傳遞查詢結果,請考慮使用一般具名結構或類別來取代匿名類型。If you must store query results or pass them outside the method boundary, consider using an ordinary named struct or class instead of an anonymous type.

由於匿名類型上的 EqualsGetHashCode 方法會以屬性的 EqualsGetHashCode 方法來定義,相同匿名類型的兩個執行個體僅在其所有屬性都相等時,這兩個執行個體才相等。Because the Equals and GetHashCode methods on anonymous types are defined in terms of the Equals and GetHashCode methods of the properties, two instances of the same anonymous type are equal only if all their properties are equal.

另請參閱See also