2009-07-29 18 views
81

mam to:Jak uzyskać dostęp do własności typu anonimowego w języku C#?

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

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

... i zastanawiam się, czy mogę wtedy chwycić „zaznaczone” własność anonimowego obiektu. Nie jestem pewien, czy to nawet możliwe. Próbowałem:

if (nodes.Any(n => n["Checked"] == false)) ... ale to nie działa.

Dzięki

Odpowiedz

52

Jeśli chcesz silnie typami listy anonimowych typów, musisz sporządza wykaz typ anonimowy zbyt. Najłatwiej to zrobić, wyświetlając sekwencję taką jak tablica na liście, np.

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

Wtedy będzie można uzyskać do niego dostęp, takich jak:

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

Ze względu na sposób działa kompilator, co następuje potem powinny również działać po utworzeniu listy, ponieważ anonimowych typów mają taką samą strukturę, więc są również tego samego typu. Nie mam jednak kompilatora, który mógłby to zweryfikować.

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

Jeśli przechowywania obiekt jako typ object, trzeba użyć refleksji. Dotyczy to dowolnego typu obiektu, anonimowego lub w inny sposób. Na obiekt O, można uzyskać jego typ:

Type t = o.GetType(); 

Następnie niż spojrzeć w górę właściwość:

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

Następnie z których można uzyskać wartość:

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

Ta odpowiedź jest już dawno oczekiwana na aktualizację C# 4:

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

A teraz kolejna alternatywa w C# 6:

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

Należy pamiętać, że za pomocą ?. powodujemy otrzymany v być null w trzech różnych sytuacjach!

  1. o jest null, więc nie ma żadnego obiektu w ogóle
  2. o jest nie- null ale nie mają właściwość Foo
  3. o ma właściwość Foo ale jego prawdziwa wartość bywa null.

To nie jest odpowiednik wcześniejszych przykładów, ale może mieć sens, jeśli chcesz, aby wszystkie trzy przypadki były takie same.

+4

Nigdy nie stosować przed dynamicznym dotychczas, miła zmiana do .NET 4.0 – Alan

+1

woow, dobre dla C# 4 = D to działa dla mnie – ch2o

+0

w rozwiązaniu C# otrzymasz wyjątek czasu wykonywania, jeśli właściwość nie istnieje ('object v = d.Foo'), natomiast' GetValue (o, null) 'będzie null, jeśli nie istnieje. – kobe

12

Można wykonywać iteracje nad właściwościami anonimowego typu za pomocą Reflection; Sprawdź, czy istnieje właściwość "Sprawdzona" i czy istnieje jej wartość.

Zobacz ten post na blogu: http://blogs.msdn.com/wriju/archive/2007/10/26/c-3-0-anonymous-type-and-net-reflection-hand-in-hand.aspx

Więc coś takiego:

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

Jeśli potrzebujesz tylko jednej nieruchomości i znasz już jej nazwę, nie ma sensu przeglądać ich wszystkich; po prostu użyj GetProperty i GetValue. Również System.out.println to Java, a nie C# ... –

+0

Oops, więc tak jest, Chris! Trochę krępujące ... naprawione teraz. – glennkentwell

Powiązane problemy