Анонимные типы (Руководство по программированию в 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.

В следующем примере показан анонимный тип, инициализированный с помощью двух свойств — Amount и Message.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 включает свойства Color и Price, а также другие свойства, в которых вы не заинтересованы.Class Product includes Color and Price properties, together with other properties that you are not interested in. Переменная products является коллекцией объектов Product.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. В следующем примере используются имена свойств анонимного типа Color и Price.In 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

Анонимные типы являются типами class, прямыми производными от типа object, и не могут быть приведены ни к какому иному типу, кроме object.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. С точки зрения среды CLR анонимный тип не отличается от других ссылочных типов.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. Для передачи анонимного типа или коллекции, содержащей анонимные типы, как аргумента для метода можно использовать этот параметр в качестве объекта типа.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.

Так как методы Equals и GetHashCode в анонимных типах определяются через методы Equals и GetHashCode свойств, два экземпляра одного и того же анонимного типа равны, только если равны их свойства.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