2013-08-17 6 views
5

Ich habe ein wenig über Reflexionen in C# geforscht und würde gerne wissen, ob ich ein Dictionary mit keys-values ​​verwende, um ein Objekt mit der Variablen mit dem Namen zu erzeugen jedes Schlüssels im Wörterbuch und deren Werte der Schlüsselwert dieses Wörterbuchs.Erzeuge dynamisches Objekt aus dem Wörterbuch mit C# Reflection

Ich habe eine Methode, die das Gegenteil tut, das ein Objekt aus einem Wörterbuch extrahiert, enthält dieses Wörterbuch die Schlüssel und die Klasseneigenschaften und ihre Werte, den Wert der Eigenschaften.

Ich frage mich, wie das geht, wenn möglich.

Unten ist meine Methode, die ein Wörterbuch eines Objekts extrahiert:

protected Dictionary<String, String> getObjectProperty(object objeto) 
{ 
    Dictionary<String, String> dictionary = new Dictionary<String, String>(); 

    Type type = objeto.GetType(); 
    FieldInfo[] field = type.GetFields(); 
    PropertyInfo[] myPropertyInfo = type.GetProperties(); 

    String value = null; 

    foreach (var propertyInfo in myPropertyInfo) 
    { 
     if (propertyInfo.GetIndexParameters().Length == 0) 
     { 
      value = (string)propertyInfo.GetValue(objeto, null); 
      value = value == null ? null : value; 
      dictionary.Add(propertyInfo.Name.ToString(), value); 
     } 
    } 

    return dictionary; 
} 
+2

Wollen Sie 'dynamisch' typisierte Objekt? Oder einen neuen Typ erstellen? – Euphoric

+0

Welche Version von .NET Framework verwenden Sie? –

+0

Das Objekt existiert bereits, wenn ich diese Funktion verlasse, muss ich (myObject) nur das Ergebnis davon in das existierende Objekt umwandeln. .NET 4.0 –

Antwort

2

Ich bin nicht sicher, ob dies ist, was Sie suchen, aber Ihre Frage zu urteilen, glaube ich Ihnen wollen Instanziieren von Typen zur Laufzeit aus den Typen, die sich in einem Wörterbuch befinden, die durch Bereitstellen eines Schlüssels erhalten werden.

Wenn das so ist, dann können Sie die folgende Klasse erstellen, die Schlüssel-Wert-Paare von Strings enthält, die Ihre Schlüssel sein werden, und Typen, die Ihre Werte repräsentieren, die instanziiert werden.

class DictionaryActivator 
{ 
    Dictionary<string, Type> Dictionary = new Dictionary<string, Type>(); 

    public DictionaryActivator() 
    { 
     Dictionary.Add("MyCar", typeof(Car)); 
     Dictionary.Add("MyHouse", typeof(House)); 
     Dictionary.Add("MyFruit", typeof(Fruit)); 
     Dictionary.Add("MyComputer", typeof(Computer)); 
    } 

    public T GetInstance<T>(string type, params object[] parameters) 
    { 
     if (parameters.Count() == 0) 
     { 
      return (T)Activator.CreateInstance(Dictionary[type]); 
     } 
     else 
     { 
      return (T)Activator.CreateInstance(Dictionary[type], parameters.ToArray()); 
     } 
    } 
} 

Sie können auch vier Testklassen erstellen, um diese Einrichtung zu testen.

class House 
{ 
    public int Number = 25; 
} 

class Car 
{ 
    public double Price = 50000; 
} 

class Fruit 
{ 
    public string Name = "Apple"; 
} 

class Computer 
{ 
    public string Cpu { get; set; } 
    public string Gpu { get; set; } 

    public Computer(string cpu, string gpu) 
    { 
     Cpu = cpu; 
     Gpu = gpu; 
    } 
} 

Sobald dies erledigt ist, können Sie die folgenden Zeilen von Code ausführen, um alle Typen aus dem Wörterbuch zu bekommen, instanziiert sie und werfen sie zu entsprechenden Typen. Wie Sie vielleicht bemerken, zeigt das letzte Computer Beispiel, wie Sie der neu erstellten Instanz mehrere Parameter (in diesem Fall zwei) hinzufügen und sie als Instanz vom Typ Objekt zurückgeben.

Am Ende können Sie es in den Computer Typ umwandeln, damit Sie überprüfen können, dass die Konstruktorparameter tatsächlich zu den entsprechenden Eigenschaften gingen.

class Program 
{ 
    static void Main() 
    { 
     var source = new DictionaryActivator(); 

     Console.WriteLine(source.GetInstance<Car>("MyCar").Price); 
     Console.WriteLine(source.GetInstance<House>("MyHouse").Number); 
     Console.WriteLine(source.GetInstance<Fruit>("MyFruit").Name); 

     var computer = source.GetInstance<object>("MyComputer", "Fast CPU", "Fast GPU"); 

     Console.WriteLine((computer as Computer).Cpu); 
     Console.WriteLine((computer as Computer).Gpu); 

     Console.Read(); 
    } 
} 
+0

ich ein Objekt vom Typ Object erstellen und fügen Sie beispielsweise zwei Variablen dazu mit ihren Werten und zurückgeben? –

+0

Ich habe meine Antwort so bearbeitet, ja, Sie können genau das tun. Übergeben Sie einfach so viele Parameter an Ihre neue Instanz, und übergeben Sie sie an ein Objekt, indem Sie den generischen Typ verwenden, der in der Methode GetInstance (string, params object []) definiert ist. –

11

Wenn Sie bereits ein Wörterbuch bekam, würde ich Reflexion vermeiden und verwenden nur DynamicObject

Zum Beispiel:

public class DynamicDictionary : DynamicObject 
{ 
    private readonly Dictionary<string, object> dictionary; 

    public DynamicDictionary(Dictionary<string, object> dictionary) 
    { 
     this.dictionary = dictionary; 
    } 

    public override bool TryGetMember(
     GetMemberBinder binder, out object result) 
    { 
     return dictionary.TryGetValue(binder.Name, out result); 
    } 

    public override bool TrySetMember(
     SetMemberBinder binder, object value) 
    { 
     dictionary[binder.Name] = value; 

     return true; 
    } 
} 

die verwendet werden können, wie folgt:

dynamic x = new DynamicDictionary(
    new Dictionary<string, object> {{"Name", "Peter"}}); 

Console.WriteLine(x.Name); 
1

Da ExpandoObject ein Wörterbuch ist, können Sie diese Erweiterungsfunktion verwenden:

public static object With(this IDictionary<string, object> obj, IDictionary<string,object> additionalProperties) 
{ 
    foreach (var name in additionalProperties.Keys) 
    obj[name] = additionalProperties[name]; 
    return obj; 
} 

Verbrauch:

var dynamicObj = new System.Dynamic.ExpandoObject().With(myDictionary); 
Verwandte Themen