2013-08-17 39 views
5

Tôi đã nghiên cứu một chút về phản xạ trong C# và muốn biết nếu tôi sử dụng từ điển có khóa-giá trị có thể tạo đối tượng có biến với tên không của mỗi khóa trong từ điển và giá trị của chúng, giá trị khóa của từ điển đó.Tạo đối tượng động từ điển với C# Reflection

Tôi có phương pháp ngược lại, trích xuất một đối tượng từ một từ điển, từ điển này chứa các khóa và thuộc tính lớp và giá trị của chúng, giá trị của thuộc tính.

Tôi tự hỏi cách thực hiện việc này nếu có thể.

Dưới đây là phương pháp của tôi, được chiết xuất một cuốn từ điển của một đối tượng:

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

Bạn có nghĩa là đối tượng gõ 'năng động'? Hoặc tạo loại mới? – Euphoric

+0

Phiên bản .NET framework nào bạn sử dụng? –

+0

Đối tượng đã tồn tại, khi thoát chức năng này, tôi chỉ cần truyền (myObject) kết quả của đối tượng đó tới đối tượng hiện có. .NET 4.0 –

Trả lời

2

Tôi không chắc chắn nếu điều này là những gì bạn đang tìm kiếm, nhưng đánh giá bởi câu hỏi của bạn, tôi nghĩ bạn muốn các loại khởi tạo vào thời gian chạy từ các loại nằm trong từ điển, sẽ được lấy bằng cách cung cấp khóa.

Nếu đúng như vậy, bạn có thể tạo lớp sau sẽ giữ cặp khóa-giá trị của chuỗi sẽ là khóa của bạn và các loại sẽ đại diện cho giá trị của bạn sẽ được khởi tạo.

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

Bạn cũng có thể tạo bốn lớp thử nghiệm để kiểm tra thiết lập này.

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

Sau khi thực hiện xong, bạn có thể chạy các dòng mã sau đây để nhận tất cả các loại từ điển, khởi tạo chúng và truyền chúng sang các loại thích hợp. Như bạn có thể nhận thấy, ví dụ Máy tính mới nhất đang cho bạn thấy cách thêm nhiều tham số (trong trường hợp này là hai) vào cá thể mới tạo và trả về trường hợp kiểu đối tượng.

Cuối cùng, bạn có thể truyền nó sang loại Máy tính để bạn có thể kiểm tra xem các thông số của hàm tạo có thực sự đi đến các thuộc tính tương ứng hay không.

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

tôi có thể tạo một đối tượng của kiểu Object và thêm ví dụ hai biến với giá trị của chúng và trả về? –

+0

Tôi đã chỉnh sửa câu trả lời của tôi để có, bạn có thể làm chính xác điều đó. Chỉ cần truyền bao nhiêu tham số mà bạn muốn dụ mới của bạn và đưa nó vào một đối tượng bằng cách sử dụng kiểu generic được định nghĩa trên phương thức GetInstance (string, params object []). –

11

Nếu bạn đã có một cuốn từ điển, tôi muốn tránh phản chiếu và chỉ sử dụng DynamicObject

Ví dụ:

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

Mà có thể được sử dụng như sau:

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

Console.WriteLine(x.Name); 
1

ExpandoObject là từ điển, bạn có thể sử dụng chức năng mở rộng này:

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

Cách sử dụng:

var dynamicObj = new System.Dynamic.ExpandoObject().With(myDictionary); 
Các vấn đề liên quan