C#:如何在运行时向对象添加属性?
作为一个实体类,我想在运行时添加一个属性,我该怎么办?
需要看什么属性? 如果它是数据绑定等, TypeDescriptor
应该工作:
TypeDescriptor.AddAttributes(type, attribs); TypeDescriptor.AddAttributes(instance, attribs);
这只会影响System.ComponentModel
使用(不是直接reflection),但这通常就足够了 – 例如,您可以通过上面的方式关联TypeConverter
。
如果“属性”是指“属性”,那么(同样,就数据绑定而言) TypeDescriptor
也有潜力 – 但它是非平凡的; 您需要在对象上实现ICustomTypeDescriptor
,或者为类型编写CustomTypeDescriptor
– 在任何一种情况下,您都需要编写自己的PropertyDescriptor
实现(通常与每个实例字典交谈等)。 任何使用的东西都会使用它:
// only works if you use TypeDescriptionProvider PropertyDescriptorCollection typeProps = TypeDescriptor.GetProperties(type); // works via TypeDescriptionProvider or ICustomTypeDescriptor PropertyDescriptorCollection objProps = TypeDescriptor.GetProperties(obj);
同样,这涵盖了广泛的数据绑定和类似场景。 举个例子, 请看这里 – 然而,这远非微不足道。 示例用法(来自链接)在运行时添加两个属性:
Bag.AddProperty("TestProp", new DefaultValueAttribute(5)); Bag.AddProperty("Name");
编辑:请澄清,您是在谈论c#属性还是您class上的成员?
添加c#属性的唯一方法是使用其他属性生成一个全新的类,编译并将新程序集加载到现有的AppDomain。
使用哈希表来存储您的属性。
如果您想要更多的运行时灵活性,可以尝试Ruby或其他一些解释语言。
看看动态语言运行时。 您也可以考虑使用IronRuby或IronPython等动态语言。
你试图解决什么问题?
属性是类型的元数据的一部分,因此它们在编译的程序集中被硬编码(这也是为什么只允许使用某些基本类型而不是属性的任意数据)。
结果是您无法在运行时向类型添加任何属性。 但是有各种替代技术。 您可以使用简单的词典或更强大的function,如附加的依赖项属性 。
我会选择PostSharp ,这是一个非常优雅的AOP框架 (或Policy Injection )。
PostSharp 允许您注入自定义属性 。
在post中提到的博客条目中有一些代码可以下载以实现您的目标。
这篇文章为我解答了这个:
在运行时动态创建类型