在运行时添加属性
我有一个程序员可以用来动态添加新属性的类。 为此,它实现了ICustomTypeDescriptor
,以便能够覆盖GetProperties()
方法。
public class DynamicProperty { public object Value { get; set; } public Type Type { get; set; } public string Name { get; set; } public Collection Attributes { get; set; } } public class DynamicClass : ICustomTypeDescriptor { // Collection to code add dynamic properties public KeyedCollection Properties { get; private set; } // ICustomTypeDescriptor implementation PropertyDescriptorCollection ICustomTypeDescriptor.GetProperties() { // Properties founded within instance PropertyInfo[] instanceProps = this.GetType().GetProperties(BindingFlags.Public | BindingFlags.Instance); // Fill property collection with founded properties PropertyDescriptorCollection propsCollection = new PropertyDescriptorCollection(instanceProps.Cast().ToArray()); // Fill property collection with dynamic properties (Properties) foreach (var prop in Properties) { // HOW TO? } return propsCollection; } }
是否可以迭代属性列表以将每个属性添加到PropertyDescriptorCollection
?
基本上我希望程序员能够将一个DynamicProperty
添加到一个将由GetProperties
处理的集合中。 就像是:
new DynamicClass() { Properties = { new DynamicProperty() { Name = "StringProp", Type = System.String, Value = "My string here" }, new DynamicProperty() { Name = "IntProp", Type = System.Int32, Value = 10 } } }
现在,只要调用GetProperties
这些Properties
就会被设置为实例属性。 我认为这是正确的方法吗?
您已经在创建这样的集合:
PropertyDescriptorCollection propsCollection = new PropertyDescriptorCollection(instanceProps.Cast().ToArray());
但是您创建的集合仅具有现有属性,而不是您的新属性。
您需要提供从现有属性和新属性连接的单个数组。
像这样的东西:
instanceProps.Cast().Concat(customProperties).ToArray()
下一个问题:您需要customProperties
,它是PropertyDescriptor
的集合。 不幸的是, PropertyDescriptor
是一个抽象类,因此您没有一种简单的方法来创建它。
我们可以解决这个问题,只需通过从PropertyDescriptor
派生并实现所有抽象方法来定义自己的CustomPropertyDescriptor
类。
像这样的东西:
public class CustomPropertyDescriptor : PropertyDescriptor { private Type propertyType; private Type componentType; public CustomPropertyDescriptor(string propertyName, Type propertyType, Type componentType) : base(propertyName, new Attribute[] { }) { this.propertyType = propertyType; this.componentType = componentType; } public override bool CanResetValue(object component) { return true; } public override Type ComponentType { get { return componentType; } } public override object GetValue(object component) { return 0; /* your code here to get a value */; } public override bool IsReadOnly { get { return false; } } public override Type PropertyType { get { return propertyType; } } public override void ResetValue(object component) { SetValue(component, null); } public override void SetValue(object component, object value) { /* your code here to set a value */; } public override bool ShouldSerializeValue(object component) { return true; } }
我没有填写调用来获取和设置你的属性; 这些调用取决于您如何在引擎盖下实现动态属性。
然后,您需要创建一个CustomPropertyDescriptor
数组,其中填入适合您的动态属性的信息,并将其连接到我最初描述的基本属性。
PropertyDescriptor
不仅描述了您的属性,还使客户端能够实际获取和设置这些属性的值。 这就是重点,不是吗!