Tự động thêm các thuộc tính C # trong thời gian chạy


89

Tôi biết có một số câu hỏi giải quyết vấn đề này, nhưng câu trả lời thường đi theo dòng đề xuất Từ điển hoặc Bộ sưu tập các tham số, điều này không hoạt động trong tình huống của tôi.

Tôi đang sử dụng một thư viện hoạt động thông qua sự phản chiếu để làm nhiều việc thông minh với các đối tượng có thuộc tính. Điều này hoạt động với các lớp đã xác định, cũng như các lớp động. Tôi cần tiến thêm một bước nữa và làm điều gì đó dọc theo những dòng sau:

public static object GetDynamicObject(Dictionary<string,object> properties) {
    var myObject = new object();
    foreach (var property in properties) {
        //This next line obviously doesn't work... 
        myObject.AddProperty(property.Key,property.Value);
    }
    return myObject;
}

public void Main() {
    var properties = new Dictionary<string,object>();
    properties.Add("Property1",aCustomClassInstance);
    properties.Add("Property2","TestString2");

    var myObject = GetDynamicObject(properties);

    //Then use them like this (or rather the plug in uses them through reflection)
    var customClass = myObject.Property1;
    var myString = myObject.Property2;

}

Thư viện hoạt động tốt với kiểu biến động, với các thuộc tính được gán thủ công. Tuy nhiên tôi không biết có bao nhiêu hoặc những thuộc tính nào sẽ được thêm vào trước.

Câu trả lời:


105

Bạn đã xem qua ExpandoObject chưa?

xem: http://blogs.msdn.com/b/csharpfaq/archive/2009/10/01/dynamic-in-c-4-0-introductioning-the-expandoobject.aspx

Từ MSDN:

Lớp ExpandoObject cho phép bạn thêm và xóa các thành viên của các thể hiện của nó tại thời điểm chạy và cũng có thể đặt và nhận các giá trị của các thành viên này. Lớp này hỗ trợ liên kết động, cho phép bạn sử dụng cú pháp chuẩn như sampleObject.sampleMember thay vì cú pháp phức tạp hơn như sampleObject.GetAttribute ("sampleMember").

Cho phép bạn làm những điều thú vị như:

dynamic dynObject = new ExpandoObject();
dynObject.SomeDynamicProperty = "Hello!";
dynObject.SomeDynamicAction = (msg) =>
    {
        Console.WriteLine(msg);
    };

dynObject.SomeDynamicAction(dynObject.SomeDynamicProperty);

Dựa trên mã thực tế của bạn, bạn có thể quan tâm hơn:

public static dynamic GetDynamicObject(Dictionary<string, object> properties)
{
    return new MyDynObject(properties);
}

public sealed class MyDynObject : DynamicObject
{
    private readonly Dictionary<string, object> _properties;

    public MyDynObject(Dictionary<string, object> properties)
    {
        _properties = properties;
    }

    public override IEnumerable<string> GetDynamicMemberNames()
    {
        return _properties.Keys;
    }

    public override bool TryGetMember(GetMemberBinder binder, out object result)
    {
        if (_properties.ContainsKey(binder.Name))
        {
            result = _properties[binder.Name];
            return true;
        }
        else
        {
            result = null;
            return false;
        }
    }

    public override bool TrySetMember(SetMemberBinder binder, object value)
    {
        if (_properties.ContainsKey(binder.Name))
        {
            _properties[binder.Name] = value;
            return true;
        }
        else
        {
            return false;
        }
    }
}

Theo cách đó, bạn chỉ cần:

var dyn = GetDynamicObject(new Dictionary<string, object>()
    {
        {"prop1", 12},
    });

Console.WriteLine(dyn.prop1);
dyn.prop1 = 150;

Bắt nguồn từ DynamicObject cho phép bạn đưa ra chiến lược của riêng mình để xử lý các yêu cầu thành viên động này, hãy cẩn thận có những con quái vật ở đây: trình biên dịch sẽ không thể xác minh nhiều cuộc gọi động của bạn và bạn sẽ không nhận được intellisense, vì vậy hãy tiếp tục điều đó trong tâm trí.


39

Cảm ơn @Clint vì câu trả lời tuyệt vời:

Chỉ muốn làm nổi bật việc giải quyết vấn đề này dễ dàng như thế nào bằng cách sử dụng Đối tượng Expando:

    var dynamicObject = new ExpandoObject() as IDictionary<string, Object>;
    foreach (var property in properties) {
        dynamicObject.Add(property.Key,property.Value);
    }

3

bạn có thể giải mã chuỗi json của mình vào một từ điển và sau đó thêm các thuộc tính mới rồi tuần tự hóa nó.

 var jsonString = @"{}";

        var jsonDoc = JsonSerializer.Deserialize<Dictionary<string, object>>(jsonString);

        jsonDoc.Add("Name", "Khurshid Ali");

        Console.WriteLine(JsonSerializer.Serialize(jsonDoc));
Khi sử dụng trang web của chúng tôi, bạn xác nhận rằng bạn đã đọc và hiểu Chính sách cookieChính sách bảo mật của chúng tôi.
Licensed under cc by-sa 3.0 with attribution required.