动态添加C#属性在运行时(Dynamically Add C# Properties at Runt

2019-08-19 15:04发布

我知道有一些解决这个问题,但答案通常沿着推荐的参数的字典或集合,这并不在我的情况下工作的行跟进。

我使用的是通过反射工作做大量的聪明的事情与属性的对象库。 这适用于定义的类,以及动态类。 我需要进一步采取这一步,做这些方针的东西:

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;

}

库正常工作与动态变量类型,具有属性手动分配。 但是我不知道有多少或什么样的属性会被预先添加。

Answer 1:

你已经采取了看看ExpandoObject?

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

从MSDN:

该ExpandoObject类,可以添加在运行时删除其实例的成员,还来设置和获取这些成员的值。 该类支持动态绑定,从而使您能够使用标准语法像sampleObject.sampleMember,而不是更复杂的语法像sampleObject.GetAttribute(“sampleMember”)。

让你做很酷的事情,如:

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

dynObject.SomeDynamicAction(dynObject.SomeDynamicProperty);

根据您的实际代码,你可能会更感兴趣的是:

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

这样,你只需要:

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

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

从DynamicObject推导可以让你拿出自己的策略来处理这些动态成员的要求, 这里要注意会有怪物:编译器将无法核实你的很多动态调用的,你不会得到智能感知,所以还是考虑到这一点。



Answer 2:

感谢@Clint为伟大的答案:

只想强调它是多么容易解决这个使用Expando的对象:

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


文章来源: Dynamically Add C# Properties at Runtime