2009-07-17 5 views
9

I potrzeba, aby wykryć, czy obiekt został stworzony anonimowo jak nowy {nazwa = wartość}C# Wykrywanie AnonymousType new {name = wartość} i przekształcić Dictionary <string, object>

jeśli jest to AnonymousType, należy dodać, że to nazwy właściwości/wartości w

Dictionary<string,object> 

to właśnie włamał się razem sobie:

var name="name"; 

var obj = new { name = new object(), }; 

var lookup = new Dictionary<string,object>(); 


if(obj.GetType().Name.StartsWith("<>f__AnonymousType")) 
{ 
    foreach (var property in obj.GetType().GetProperties()) 
    { 
     lookup[property.Name] = property.GetValue(obj, null); 
    } 
} 
else 
{ 
    lookup[name]=obj; 
} 

zastanawiałem się, czy istnieje lepszy/szybszy sposób wykrywania AnonymousTypes, lub jeśli istnieje lepszy/szybszy sposób zrzucić właściwości nazwy obiektu w/wartości do

Dictionary<string,object> 
+0

Co próbujesz osiągnąć z tym? Cokolwiek to jest, musi istnieć lepszy sposób na zrobienie tego. –

Odpowiedz

24

Aby uzyskać wszystkie właściwości obiektu, z jego wartościami na Dictionary, można połączyć moc Linq z obiektami z odbiciem.

Można użyć metody Enumerable.ToDictionary:

var dic = obj.GetType() 
      .GetProperties() 
      .ToDictionary(p => p.Name, p=> p.GetValue(obj, null)); 

To będzie powrót do Dictionary<string, object>.

+0

Problem polega na tym, że może on po prostu użyć słownika, byłoby to znacznie szybsze, gdyby Linq nie robił jakiegoś zwariowanego buforowania w tym zapytaniu, w którym to przypadku byłby "tylko" mierzalnie szybszy. –

+0

Co zrobić, jeśli widzę właściwości "wewnętrzne", takie jak "GenericEqualityComparer", a nie właściwości jawnie zadeklarowane? Próbowałem 'GetProperties (BindingFlags.DeclaredOnly)'. – drzaus

+0

Dziwne, nieważne - odkryłem, że metoda używająca tego odbicia (samego w rozszerzeniu obiektu) zakończyła wywoływanie samego siebie z przekonwertowanym wynikiem, więc moje rozszerzenie zostało wywołane na obiekcie ORAZ NA wynikowym słowniku. – drzaus

6

Użyj nowej składni initializer obiektu kolekcja zamiast typu anonimowego:

var obj = new Dictionary<string, object>() 
{ 
    { "Name", t.Name }, 
    { "Value", t.Value } 
}; 
2

wykrywania anonimowy type to little hard; nie tylko to zależy od języka! Typy antywirusowe VB nie wyglądają tak samo jak C# anon-types. Byłbym wątpliwy w logikę, która działa inaczej na typy anonowe. Możesz sprawdzić na [CompilerGenerated], ale zauważ, że nie oznacza to tylko "anonimowego typu" - są też inne, które to robią.

Osobiście nie rozróżniałbym w tym scenariuszu.

Powiązane problemy