2013-07-12 21 views
5

Próbuję uzyskać dostęp do obiektu przechowywanego w słowniku typu String, UnknownClass. Mam klucz i wiem, że wartość jest jedną z kilku klas kontenera. Ponieważ wartość jest przekazywana do metody, która pobiera obiekt, nie potrzebuję znać typu klasy przechowywanej jako wartość. Muszę również wywołać ContainsKey, aby potwierdzić, że klucz istnieje.Uzyskaj wartość słownika za pomocą refleksji

Próbowałem następujące metody bez powodzenia:

Dictionary<String, object> list = (Dictionary<String, object>)source.GetType().GetProperty(dictionaryName).GetValue(source, null); 
nextSource = list[key]; 

co daje mi błąd odlewniczej oraz:

nextSource = source.GetType().GetMethod("get_Item").Invoke(source, new object[] { key }); 

co daje mi wyjątku null odniesienia.

Tutaj jest trochę więcej kodu, chociaż nie jestem całkiem pewien, czy to pomoże.

private void SetValue(object source, String path, String value) 
{ 
    if (path.Contains('.')) 
    { 
     // If this is not the ending Property, continue recursing 
     int index = path.IndexOf('.'); 
     String property = path.Substring(0, index); 

     object nextSource; 
     if(property.Contains("*")) 
     { 
      path = path.Substring(index + 1); 
      index = path.IndexOf('.'); 
      String dictionaryName = path.Substring(0, index); 

      Dictionary<String, object> list = (Dictionary<String, object>)source.GetType().GetProperty(dictionaryName).GetValue(source, null); 
      nextSource = list[property.Substring(1)]; 
      //property = property.Substring(1); 
      //nextSource = source.GetType().GetMethod("Item").Invoke(source, new[] { property }); 
     } ... 

Słownik uzyskiwany jest określony w klasie PersonObject jako takie:

public class PersonObject 
{ 
    public String Name { get; set; } 
    public AddressObject Address { get; set; } 
    public Dictionary<String, HobbyObject> Hobbies { get; set; } 

Wartość ścieżki, na tym etapie jest ustawiony "*Hiking.Hobbies.Hobby". Zasadniczo, ciąg znaków pozwala mi przejść do właściwości w podklasie i potrzebuję Słownika, aby uzyskać dostęp do właściwości dla listy tej samej klasy.

+0

Czy potwierdzone, że 'source.GetType() GetProperty (dictionaryName) .GetValue (source, null) 'zwraca referencję do słownika lub zwraca" null "? EDYCJA: jeśli zwraca poprawnie słownik, może po prostu użyj 'dynamic' zamiast:' dynamic list = (dynamic) source.GetType(). GetProperty (dictionaryName) .GetValue (source, null); nextSource = (obiekt) lista [klucz]; ' –

+0

am cholernie pewne źródło ma wartość null, jeśli nie powinno to działać –

+0

Źródło nie jest puste. Kiedy nazywam to, otrzymuję wyjątek InvalidCastException. Rzeczywisty słownik, do którego uzyskuję dostęp w tym konkretnym przykładzie, to typ . – Tim

Odpowiedz

7

The Dictionary<TKey, TValue> Class realizuje nierodzajową IDictionary Interface. Więc jeśli masz zmienną Tye object zawierającej odwołanie do instancji Dictionary<String, HobbyObject> można pobierać wartości w słowniku, co następuje:.

object obj = new Dictionary<String, HobbyObject> 
{ 
    { "Hobby", new HobbyObject() } 
}; 

IDictionary dict = obj as IDictionary; 
if (dict != null) 
{ 
    object value = dict["Hobby"]; 
    // value is a HobbyObject 
} 
3

Brzmi jak próbujesz to zrobić:

var source = new Dictionary<string, object>(); 
var key = "some key"; 
source.Add(key, "some value"); 

var property = source.GetType().GetProperty("Item"); 
var value = property.GetValue(source, new[] { key }); 

Console.WriteLine(value.ToString()); // some value 

Aktualizacja: Problemem jest to, że Dictionary<string, HobbyObject> nie może być rzucony na Dictionary<string, object>. Myślę, że trzeba to zrobić:

private void SetValue(object source, String path, String value) 
{ 
    if (path.Contains('.')) 
    { 
     // If this is not the ending Property, continue recursing 
     int index = path.IndexOf('.'); 
     String property = path.Substring(0, index); 

     object nextSource; 
     if(property[0] = '*') 
     { 
      path = path.Substring(index + 1); 
      index = path.IndexOf('.'); 
      String dictionaryName = path.Substring(0, index); 

      property = property.Substring(1); 

      Object list = source.GetType().GetProperty(dictionaryName) 
           .GetValue(source, null); 
      nextSource = list.GetType().GetProperty("Item") 
          .GetValue(list, new[] { property }); 
     } 
+0

Zmodyfikowałem kod na następujący: nextSource = source.GetType(). GetMethod ("Item"). Invoke (source, new [] {property}); Niestety nadal otrzymuję wyjątek odwołania zerowego.Sprawdziłem i sprawdzono zarówno "źródło", jak i "właściwość". – Tim

+0

@Tim Być może źle zrozumiałem twój problem; ciężko jest zobaczyć, gdzie może być twój problem. Opublikuj więcej kodu, aby zobaczyć pełny kontekst. –

+0

Dziękuję za pomoc. Zmodyfikowałem pytanie za pomocą dodatkowego kodu, chociaż nie jestem pewien, ile to naprawdę pomoże. – Tim

Powiązane problemy