Как следует использовать анонимные типы в C #?

Я видел множество описаний того, как работают анонимные типы, но не уверен, насколько они действительно полезны. Для каких сценариев анонимные типы могут использоваться в хорошо спроектированной программе?


person readonly    schedule 07.09.2008    source источник


Ответы (7)


Анонимные типы не имеют ничего общего с дизайном систем или даже на уровне классов. Это инструмент, который разработчики могут использовать при кодировании.

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

Например:

var query = from item in database.Items
            // ...
            select new { Id = item.Id, Name = item.Name };

return query.ToDictionary(item => item.Id, item => item.Name);

Никому нет дела до анонимного типа a. Он там, поэтому вам не нужно объявлять другой класс.

person Omer van Kloeten    schedule 07.09.2008
comment
Вам это когда-нибудь нужно. Конечно, если вы делаете так много в своем методе, что он требует анонимного типа, вам следует провести рефакторинг метода. В вашем примере вы запрашиваете БД, а затем изменяете результаты ... это два разных метода для меня. - person EightyOne Unite; 10.09.2010
comment
Я не изменяю результаты, я трансмутирую их в какую-то другую форму, которую легче вернуть. Следует быть осторожным, чтобы не перераспределять свой код по нескольким методам, потому что это сделает код полностью нечитаемым и создаст, поскольку нет возможности использовать анонимные типы, много либо уродливого кода, либо избыточных типов, закодированных вручную. - person Omer van Kloeten; 16.09.2010

Из LINQ в действии (стр. 76, раздел 2.6.3):

... анонимные типы [являются] отличным инструментом для быстрых и простых временных результатов. Нам не нужно объявлять классы для хранения временных результатов благодаря временным типам.

в основном они полезны для временного хранения информации в локальной области. Все остальное требует использования рефлексии и может стать серьезной проблемой. Пример, который они приводят в процитированной выше книге, представляет собой письменное подтверждение идентификатора, имени и объема памяти, занимаемой каждым запущенным процессом. Они создают анонимный тип, добавляют его в список (все в одном операторе), а затем используют ObjectDumper для его вывода. Следовательно, коду больше не нужен отдельно объявленный класс для хранения идентификатора, имени и используемой памяти, но все это объявлено неявно, в результате чего счетчик строк уменьшается до 4:

var pl = new List<Object>();
foreach(var p in Process.GetProcesses())
  pl.Add(new {p.Id, p.ProcessName, Memory=p.WorkingSet64});
ObjectDumper.Write(pl);
person George Mauer    schedule 07.09.2008

Чаще всего анонимные типы используются для указания проекций в запросе LINQ to SQL.

Этот запрос

from x in db.Table1 select new {x.Column1, Alias2=x.Column2}

будет преобразован в этот SQL:

SELECT Column1, Column2 AS Alias2 FROM Table1

С анонимными типами вы можете создавать специальные прогнозы без предварительного определения для них типа. Компилятор определит тип за вас.

person Mark Cidade    schedule 03.10.2008

Когда вы создаете типы для целей «Использовать и выбросить». Похоже, это произошло из-за LINQ. Кажется, это способ на лету создавать структуры с полями для запроса LINQ. Возврат структуры / типа только с указанными полями. Если бы не это, вам пришлось бы объявлять тип .Net для каждой уникальной комбинации полей, которую вы хотите получить.

person Gishu    schedule 07.09.2008

Используйте их с Linq.

person Registered User    schedule 07.09.2008

Важно знать, что LINQ не заставляет вас использовать анонимные типы. Вы также можете писать обычные конструкции объектов после выбора.

var query = from item in database.Items
// ...
select new Person(item.id, item.Name)

Это предохраняет вас от уродливого программирования с отражением.

person ChaosSpeeder    schedule 03.10.2008

@Wouter:

var query = from item in database.Items
select new Person
{
ID =item.id,
NAME= item.Name
};

где ID и NAME являются реальной собственностью вашего класса Person.

person Community    schedule 20.05.2009
comment
Это не анонимный тип - person Joe; 29.10.2014
comment
это использует инициализатор объекта, а не анонимный тип - person Tobi Owolawi; 13.11.2018