Работа с анонимными типами C #

Я вызываю метод, который возвращает переменную List, которая содержит объекты AC # анонимного типа. Например:

List list = new List(); foreach ( Contact c in allContacts ) { list.Add( new { ContactID = c.ContactID, FullName = c.FullName }); } return list; 

Как ссылаться на свойства этого типа в коде, над которым я работаю, например,

 foreach ( object o in list ) { Console.WriteLine( o.ContactID ); } 

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

Благодаря!

Решение :

Не один из ответов правильный и / или предлагает рабочее решение. Я закончил использовать вариант 3 ответа Грега. И я узнал что-то очень интересное относительно dynamic в .NET 4.0!

Вы не можете вернуть список анонимного типа, это должен быть список object . Таким образом, вы потеряете информацию о типе.

Опция 1
Не используйте анонимный тип. Если вы пытаетесь использовать анонимный тип более чем одним методом, создайте настоящий class.

Вариант 2
Не подталкивайте анонимный тип к object . (должен быть одним способом)

 var list = allContacts .Select(c => new { c.ContactID, c.FullName }) .ToList(); foreach (var o in list) { Console.WriteLine(o.ContactID); } 

Вариант 3
Используйте ключевое слово dynamic. (Требуется .NET 4)

 foreach (dynamic o in list) { Console.WriteLine(o.ContactID); } 

Вариант 4
Используйте грязное reflection.

 foreach ( var o in list ) { Console.WriteLine( o.ContactID ); } 

это будет работать, только если список IEnumerable , например:

 var list = allContacts.Select(c => new { ContactID = c.ContactID, FullName = c.FullName }); } 

но вы не можете возвращать анонимные типы, потому что вы должны определить тип возврата (вы не можете вернуть var ), а анонимные типы не могут иметь имена. вам нужно создать не-анонимный тип, если вы его передадите. На самом деле анонимные типы не должны использоваться слишком много, за исключением внутренних запросов.

Если у вас есть такой метод:

  List GetContactInfo() { List list = new List(); foreach ( Contact c in allContacts ) { list.Add( new { ContactID = c.ContactID, FullName = c.FullName }); } return list; } 

Вы не должны этого делать, но есть очень уродливый, а не будущий метод, который вы можете использовать:

  static T CastByExample(object target, T example) { return (T)target; } // ..... var example = new { ContactID = 0, FullName = "" }; foreach (var o in GetContactInfo()) { var c = CastByExample(o, example); Console.WriteLine(c.ContactID); } 

Он полагается на факт (который может измениться!), Что компилятор повторно использует анонимные типы для типов с одинаковой «формой» (именами и типами свойств). Так как ваш «пример» соответствует «форме» типа в методе, тот же тип используется повторно.

Динамические переменные в C # 4 – лучший способ решить эту проблему.

Вы не можете сделать это с анонимными типами. Просто создайте class / структуру Contact и используйте это.

 List list = new List(); foreach ( Contact c in allContacts ) { list.Add( c ); } 

Тогда вы можете сделать это:

 foreach ( var o in list ) { Console.WriteLine( o.ContactID ); } 

…или это:

 foreach ( object o in list ) { Console.WriteLine( ((Contact)o).ContactID ); //Gives intellisense } 

Конечно, вы должны в этом случае просто создать список контактов вместо списка объектов:

 List list = new List(); foreach ( Contact c in allContacts ) { list.Add( c ); } 

EDIT: Пропущенная важная часть вопроса. Теперь исправлено.
EDIT: Изменен ответ еще раз. См. Выше.

замена объекта var на каждую конструкцию может работать

Я знаю, что опаздываю на вечеринку, но я изучаю что-то еще и нашел эту статью, которая отвечает на ваш вопрос.

Можно вернуть список объектов обратно в анонимный тип.

  public static void Main() { foreach (object item in GetList()) { var x = Cast(item, new { ContactID = 0, FullName = "" }); Console.WriteLine(x.ContactID + " " + x.FullName); } } public static IEnumerable GetList() { yield return new { ContactID = 4, FullName = "Jack Smith" }; yield return new { ContactID = 5, FullName = "John Doe" }; } public static T Cast(object obj, T type) { return (T)obj; } 

назад назад

 public static void Main() { foreach (object item in GetList()) { var x = Cast(item, new { ContactID = 0, FullName = "" }); Console.WriteLine(x.ContactID + " " + x.FullName); } } public static IEnumerable GetList() { yield return new { ContactID = 4, FullName = "Jack Smith" }; yield return new { ContactID = 5, FullName = "John Doe" }; } public static T Cast(object obj, T type) { return (T)obj; } 

я хотел бы использовать

 allContacts .Select(c => new { c.ContactID, c.FullName }) .ToList() .ForEach(c => { ...do stuff; }); 

то вам не нужно вообще объявлять. я считаю, что меньше декларации, менее полуточек приводит к меньшей ошибке

  • Будет ли динамическое ключевое слово в C # 4 поддерживать методы расширения?
  • Удаление динамически созданных элементов управления в C #
  • Можно ли создавать переменные во время выполнения на Java?
  • динамический тип объекта
  • Быстрое добавление компонента в контекст веб-приложения Spring Web
  • Interesting Posts
    Давайте будем гением компьютера.