作为一个实体类,我想在运行时添加一个属性,应该怎么做?
需要查看哪些属性?如果是像数据绑定等的东西,TypeDescriptor
应该可以解决:
TypeDescriptor.AddAttributes(type, attribs);
TypeDescriptor.AddAttributes(instance, attribs);
这仅影响System.ComponentModel
的使用(而不是直接反射),但通常足够了 - 例如,您可以通过上述方式关联TypeConverter
。
如果你所说的 "attributes" 指的是 "properties",那么(就数据绑定而言)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<int>("TestProp", new DefaultValueAttribute(5));
Bag.AddProperty<string>("Name");
使用哈希表来存储你的属性。
如果你想要更多的运行时灵活性,可以尝试使用Ruby或其他解释型语言。
属性是类型的元数据的一部分,因此它们在编译后的程序集中被硬编码(这也是为什么您只能使用某些基本类型而不能在属性中使用任意数据的原因)。
结果是您无法在运行时向类型添加任何属性。但是有各种替代技术。您可以使用简单的字典或更强大的附加依赖属性之类的东西。