2009-07-29 2 views
81

у меня есть это:Как получить доступ к свойствам анонимного типа в C#?

List<object> nodes = new List<object>(); 

nodes.Add(
new { 
    Checked  = false, 
    depth  = 1, 
    id   = "div_" + d.Id 
}); 

... и мне интересно, если я могу затем захватить «галочка» свойство анонимного объекта. Я не уверен, что это возможно. Пробовал это:

if (nodes.Any(n => n["Checked"] == false)) ... но не работает.

Благодаря

ответ

52

Если вы хотите сильно типизированный список анонимных типов, вам нужно сделать список анонимного типа тоже. Самый простой способ сделать это - проецировать последовательность, такую ​​как массив, в список, например.

var nodes = (new[] { new { Checked = false, /* etc */ } }).ToList(); 

Тогда вы сможете получить к нему доступ, как:

nodes.Any(n => n.Checked); 

Из-за тем, как компилятор работает, то следующий должен также работать, как только вы создали список, потому что анонимные типы имеют одинаковую структуру, поэтому они тоже одного типа. У меня нет компилятора, чтобы проверить это.

nodes.Add(new { Checked = false, /* etc */ }); 
200

Если вы храните объект как тип object, вам нужно использовать отражение. Это относится к любому типу объекта, анонимному или другому. На объект О, вы можете получить его тип:

Type t = o.GetType(); 

Тогда из этого вы смотрите свойство:

PropertyInfo p = t.GetProperty("Foo"); 

Тогда из этого можно получить значение:

object v = p.GetValue(o, null); 

Этот ответ давно назрел для обновления для C# 4:

dynamic d = o; 
object v = d.Foo; 

А теперь еще одна альтернатива в C# 6:

object v = o?.GetType().GetProperty("Foo")?.GetValue(o, null); 

Обратите внимание, что с помощью ?. мы вызываем в результате v быть в трех различных ситуациях null!

  1. o является null, так что нет ни одного объекта на всех
  2. o является не- null, но не обладает свойством Foo
  3. o имеет свойство Foo, но ее реальное значение случается null.

Так что это не эквивалентно предыдущим примерам, но может иметь смысл, если вы хотите рассматривать все три случая одинаково.

+4

Никогда не динамический, прежде чем до сих пор, хороший обновления для .NET 4.0 – Alan

+1

woow, хорошо для C# 4 = D это работа для меня – ch2o

+0

в решении C# 4 вы получите исключение во время выполнения, если свойство не существует ('object v = d.Foo'), а' GetValue (o, null) 'будет null, если не существует. – kobe

12

Вы можете перебирать свойства анонимного типа с помощью Reflection; посмотрите, есть ли свойство «Проверено», и есть ли тогда его значение.

Смотрите этот блог: http://blogs.msdn.com/wriju/archive/2007/10/26/c-3-0-anonymous-type-and-net-reflection-hand-in-hand.aspx

Так что-то вроде:

foreach(object o in nodes) 
{ 
    Type t = o.GetType(); 

    PropertyInfo[] pi = t.GetProperties(); 

    foreach (PropertyInfo p in pi) 
    { 
     if (p.Name=="Checked" && !(bool)p.GetValue(o)) 
      Console.WriteLine("awesome!"); 
    } 
} 
+4

Если вам нужно только одно свойство, и вы уже знаете его имя, нет смысла проходить через все из них; просто используйте GetProperty и GetValue. Кроме того, System.out.println является Java, а не C# ... –

+0

К сожалению, так, Крис! Немного неловко ... исправлено. – glennkentwell

Смежные вопросы