2013-07-12 13 views
5

Ich versuche, auf ein Objekt zuzugreifen, das in einem Wörterbuch des Typs String, UnknownClass gespeichert ist. Ich habe den Schlüssel und weiß, dass der Wert einer von mehreren Container-Klassen ist. Da der Wert an eine Methode übergeben wird, die ein Objekt übernimmt, muss ich den Typ der als Wert gespeicherten Klasse nicht kennen. Ich muss auch ContainsKey aufrufen, um zu bestätigen, dass der Schlüssel existiert.Erhalte einen Wörterbuchwert mit Reflection

Ich habe die folgenden Methoden ohne Erfolg versucht:

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

Was mir einen Casting Fehler gibt, und:

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

Was mir eine NULL-Verweis Ausnahme gibt.

Hier ist ein bisschen mehr des Codes, obwohl ich nicht ganz sicher bin, dass es viel hilft.

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 }); 
     } ... 

Das Wörterbuch zugegriffen wird, in der Klasse PersonObject als solche definiert ist:

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

Der Wert des Pfades, in diesem Stadium, ist auf "*Hiking.Hobbies.Hobby". Grundsätzlich erlaubt mir die Pfadzeichenfolge, zu einer Eigenschaft in einer Unterklasse zu navigieren, und ich benötige das Dictionary, um auf Eigenschaften für eine Liste der gleichen Klasse zuzugreifen.

+0

Haben Sie bestätigt, dass 'source.GetType() GetProperty (dictionaryName) .GetValue (source, null) 'gibt den Verweis auf das Wörterbuch zurück oder gibt es 'null' zurück? EDIT: wenn es das Wörterbuch richtig zurückgibt, vielleicht nur 'dynamische' stattdessen: 'dynamische Liste = (dynamische) source.GetType(). GetProperty (dictionaryName). GetValue (source, null); nextSource = (Objekt) Liste [Schlüssel]; ' –

+0

bin verdammt sicher Quelle ist null, wenn das nicht funktionieren sollte –

+0

Quelle ist nicht null. Wenn ich das aufrufe, erhalte ich eine InvalidCastException. Das eigentliche Wörterbuch, auf das ich für dieses Beispiel zugreife, ist vom Typ . – Tim

Antwort

7

Die Dictionary<TKey, TValue> Class implementiert die nicht generische IDictionary Interface. Also, wenn Sie eine Variable von Tye haben object den Verweis auf eine Dictionary<String, HobbyObject> Instanz enthält, können Sie Werte im Wörterbuch abrufen wie folgt:.

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

Es klingt wie Sie versuchen, dies zu tun:

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 

Update: Das Problem ist, dass ein Dictionary<string, HobbyObject> nicht auf eine Dictionary<string, object> gegossen werden kann. Ich denke, man müsste dies tun:

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

Ich habe den Code folgendermaßen geändert: nextSource = source.GetType(). GetMethod ("Element"). Invoke (source, new [] {property}); Leider bekomme ich immer noch eine Null-Referenz-Ausnahme.Ich habe überprüft, und sowohl "Quelle" und "Eigenschaft" werden überprüft. – Tim

+0

@Tim Vielleicht habe ich dein Problem missverstanden; es ist schwer zu sehen, wo dein Problem sein könnte. Bitte poste mehr Code, damit ich den vollständigen Kontext sehen kann. –

+0

Vielen Dank für Ihre Hilfe. Ich änderte die Frage mit zusätzlichem Code, obwohl ich nicht sicher bin, wie viel es tatsächlich helfen wird. – Tim