Поиск…


Создание анонимного типа

Поскольку анонимные типы не называются, переменные этих типов должны быть неявно напечатаны ( var ).

var anon = new { Foo = 1, Bar = 2 };
// anon.Foo == 1
// anon.Bar == 2

Если имена членов не указаны, они устанавливаются на имя свойства / переменной, используемого для инициализации объекта.

int foo = 1;
int bar = 2;
var anon2 = new { foo, bar };
// anon2.foo == 1
// anon2.bar == 2

Обратите внимание, что имена могут быть опущены только тогда, когда выражение в объявлении анонимного типа является простым доступом к свойствам; для вызовов методов или более сложных выражений должно быть указано имя свойства.

string foo = "some string";
var anon3 = new { foo.Length };
// anon3.Length == 11
var anon4 = new { foo.Length <= 10 ? "short string" : "long string" };
// compiler error - Invalid anonymous type member declarator.
var anon5 = new { Description = foo.Length <= 10 ? "short string" : "long string" };
// OK

Анонимный и динамический

Анонимные типы позволяют создавать объекты без явного определения их типов заблаговременно, сохраняя при этом статическую проверку типов.

var anon = new { Value = 1 };
Console.WriteLine(anon.Id); // compile time error

И наоборот, dynamic динамическая проверка типов, выбор ошибок времени выполнения, а не ошибок времени компиляции.

dynamic val = "foo";
Console.WriteLine(val.Id); // compiles, but throws runtime error

Общие методы с анонимными типами

Общие методы позволяют использовать анонимные типы посредством вывода типа.

void Log<T>(T obj) {
    // ...
}
Log(new { Value = 10 });

Это означает, что выражения LINQ могут использоваться с анонимными типами:

var products = new[] {
    new { Amount = 10, Id = 0 },
    new { Amount = 20, Id = 1 },
    new { Amount = 15, Id = 2 }
};
var idsByAmount = products.OrderBy(x => x.Amount).Select(x => x.Id);
// idsByAmount: 0, 2, 1

Создание типичных типов с анонимными типами

Использование универсальных конструкторов потребует назвать анонимные типы, что невозможно. Альтернативно, общие методы могут использоваться для разрешения вывода типа.

var anon = new { Foo = 1, Bar = 2 };
var anon2 = new { Foo = 5, Bar = 10 };
List<T> CreateList<T>(params T[] items) {
    return new List<T>(items);
}

var list1 = CreateList(anon, anon2);

В случае List<T> неявно типизированные массивы могут быть преобразованы в List<T> через метод ToList LINQ:

var list2 = new[] {anon, anon2}.ToList();

Неопределенное равенство типа

Равенство анонимного типа задается методом экземпляра Equals . Два объекта равны, если они имеют одинаковый тип и равные значения (через a.Prop.Equals(b.Prop) ) для каждого свойства.

var anon = new { Foo = 1, Bar = 2 };
var anon2 = new { Foo = 1, Bar = 2 };
var anon3 = new { Foo = 5, Bar = 10 };
var anon3 = new { Foo = 5, Bar = 10 };
var anon4 = new { Bar = 2, Foo = 1 };
// anon.Equals(anon2) == true
// anon.Equals(anon3) == false
// anon.Equals(anon4) == false (anon and anon4 have different types, see below)

Два анонимных типа считаются одинаковыми, если и только если их свойства имеют одно и то же имя и тип и отображаются в одном порядке.

var anon = new { Foo = 1, Bar = 2 };
var anon2 = new { Foo = 7, Bar = 1 };
var anon3 = new { Bar = 1, Foo = 3 };
var anon4 = new { Fa = 1, Bar = 2 };
// anon and anon2 have the same type
// anon and anon3 have diferent types (Bar and Foo appear in different orders)
// anon and anon4 have different types (property names are different)

Неявно типизированные массивы

Массивы анонимных типов могут быть созданы с неявной типизацией.

var arr = new[] {
    new { Id = 0 },
    new { Id = 1 }
};


Modified text is an extract of the original Stack Overflow Documentation
Лицензировано согласно CC BY-SA 3.0
Не связан с Stack Overflow