2013-08-17 52 views
5

我一直在研究一些關於C#中的反射,並想知道如果我使用的字典與鍵 - 值可以創建一個與變量名稱的對象字典中每個鍵的值和它們的值,即該字典的鍵值。用C#反射字典生成動態對象

我有一個相反的方法,即從字典中提取一個對象,該字典包含鍵和類屬性及其值,屬性的值。

我不知道如何做到這一點,如果可能的話。

下面是我的方法,其中提取對象的詞典:

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

你的意思是 '動態' 類型的對象?或者創建新的類型? – Euphoric

+0

您使用的是什麼版本的.NET框架? –

+0

對象已經存在,當退出這個函數時,我只需要將它的結果強制轉換(myObject)到現有的對象。 .NET 4.0 –

回答

2

我不知道,如果這是你在尋找什麼,但你的問題來看,我想你想 在運行時從位於字典中的類型實例化類型,這將通過提供一個鍵來獲得。

如果是這樣,那麼你可以創建下面的類,它將保存將作爲你的鍵的字符串鍵值對,以及表示將被實例化的值的類型。

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

您也可以創建四個測試類,來測試此設置。

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

一旦做到這一點,你可以運行下面的代碼行從字典中獲得的所有類型,實例化並將其轉換爲相應的類型。您可能會注意到,最近的示例向您展示瞭如何向新創建的實例添加多個參數(在本例中爲兩個參數),並將其作爲對象類型的實例返回。

最後,您可以將其轉換爲計算機類型,以便您可以檢查構造函數參數實際上是否轉到相應的屬性。

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

我可以創建對象類型的對象,然後添加例如兩個變量與它們的值並返回它? –

+0

我編輯了我的答案,所以是的,你可以做到這一點。只需將想要的參數傳遞給新實例,然後使用GetInstance (string,params object [])方法上定義的泛型類型將其轉換爲對象。 –

11

如果你已經有了一本字典,我會避免反光,只是使用DynamicObject

例如:

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

因而可作如下:

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

Console.WriteLine(x.Name); 
1

既然ExpandoObject是一本字典,你可以使用這個擴展功能:

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

用法:

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