动态地将具有任何名称的新属性添加到对象

时间:2014-03-08 12:14:20

标签: c#

嗯,我想这个标题解释了所有人。

我对c#中的动态世界相当新,我正在寻找一种方法来做这样的事情:

public dynamic AddPropertyToObject(Foo f, string varPropName)
{
    f.Str = "Hello";
    dynamic dynObj = f;
    dynObj.createPropertyNameAndSetValue(varPropName, "World");
    return dynObj;
}

问题是对象应该由具有任何给定名称的新属性扩展。

对象(在我的示例中为Foo)是从wsdl生成的实体,因此它不会从ExpandoObject 继承。

我怎样才能实现要扩展的对象?

createPropertyNameAndSetValue就在那里可视化我正在寻找类似这样的东西:dynObject.varPropName = "World";

顺便说一句,我正在寻找没有PropertyInfo和所有这些东西的解决方案。

如果这个问题重复,我很抱歉。在downvoting之前的评论中让我知道,我将删除它。

2 个答案:

答案 0 :(得分:3)

您无法向任何内容添加属性。您需要一个知道如何与dynamic类型系统集成的类,并且该类具有存储您添加到其中的额外属性的位置。

看看ExpandoObject。创建它的实例,然后开始在其上设置属性。

从您的评论中,您可能希望扩展现有类型以支持类似的内容。 ExpandoObject的文档仍然会帮助您;它讨论了它是如何实现的,因此它将帮助您自己实现它。备注部分解释:

  

如果要定义具有自己的动态分派语义的类型,请使用DynamicObject类。如果要定义动态对象如何参与互操作性协议并管理DLR快速动态分派缓存,请创建自己的IDynamicMetaObjectProvider接口实现。

因此,您需要将您的类更改为DynamicObject(实现IDynamicMetaObjectProvider并为您执行一些繁重的工作),或者您需要实现{{1你自己。

继续阅读文档,你会找到一篇名为Implementing Dynamic Interfaces的文章的链接,它可以帮助你决定哪种情况更好(降序或直接实现界面)。

答案 1 :(得分:0)

使用合成的解决方法。在扩展方法中将“Foo”本身作为动态对象的属性

public static object AddProperty<T>(this Object baseObject,string baseObjectPropertyName, string propertyName, T value)
{
    IDictionary<string, object> ob;
    if (baseObject is IDictionary<string, object>)
    {
        ob = baseObject as IDictionary<string, Object>;
    }
    else
    {
        ob = new ExpandoObject() as IDictionary<string, Object>;
        ob.Add(baseObjectPropertyName, baseObject);
    }
    ob.Add(propertyName, value);
    return ob;
}


var foo = new Foo();
var goingTobeIgnored = string.Empty;
dynamic ob = foo.AddProperty("FooObject","Hello", "World")
            .AddProperty(goingTobeIgnored, "AnotherHello", "AnotherWorld");