如何在.net中运行时向对象添加属性?

时间:2010-11-20 14:50:20

标签: c# .net

我正在使用第三方库来做一些工作。我将一个对象传递给lib,它对对象的每个属性执行一些操作。它使用反射枚举属性。这就是它的实现方式,我无法改变它。

我不知道lib在编译时应该处理哪些属性和多少属性。此信息仅在运行时提供。所以我不能在源代码中创建类声明。

似乎.net4的dynamic功能无法帮助我,因为lib使用反射,而非动态。

实际上我只能看到两个选项:

  1. 创建一个如下的巨大类定义:

    class Data
    {
        public object P1 {get; set;}
        public object P2 {get; set;}
        ....
        public object PN {get; set;}  // N should be at least 10.000
    }
    
  2. 在运行时生成类定义,并使用CSharpCodeProvider编译使用它。

  3. 你能建议我其他选择吗?

    遗憾的是,我不能用另一个替换这个lib。

3 个答案:

答案 0 :(得分:3)

使用第一种方法会导致高内存消耗。我会选择使用TypeBuilder类在运行时创建新类型。

答案 1 :(得分:3)

您正在寻找的内容称为Property Bag。您可以通过使用ICustomTypeDescriptor来公开其他元数据(假设您的库支持它)来实现类似的功能。

如果您的消费库直接使用Reflection(并且没有利用类型描述符等设计器功能),那么您最好的选择可能是使用其他属性动态生成代理包装器。 Castle DynamicProxy是一种很好的方法。


编辑:

实际上,我不确定Castle是否支持向代理对象添加新属性。您可能会被TypeBuilder直接使用IL Emit卡住。这是非常重要的,因为您需要充分了解IL Emit来生成属性访问器,并且还有一些学习曲线。也就是说,这是有趣而有趣的东西,如果你有时间的话,值得付出努力。

答案 2 :(得分:1)

我猜这是关于常规GUI元素,如Grid或PropertyGrid。

然后我将从反映网格接受类实例作为参数的方法开始,如果可以用我自己的vales填充内部字典或字典。

如果这是不可能的,请尝试使用System.CodeDom,而不是Emit: http://blogs.msdn.com/b/lukeh/archive/2007/07/11/c-3-0-and-codedom.aspx