2011-05-29 106 views
13

我有一個程序員可以用來動態添加新屬性的類。爲此,它實現了ICustomTypeDescriptor以便能夠覆蓋GetProperties()方法。在運行時添加屬性

public class DynamicProperty 
{ 
    public object Value { get; set; } 

    public Type Type { get; set; } 

    public string Name { get; set; } 

    public Collection<Attribute> Attributes { get; set; } 
} 

public class DynamicClass : ICustomTypeDescriptor 
{ 
    // Collection to code add dynamic properties 
    public KeyedCollection<string, DynamicProperty> 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<PropertyDescriptor>().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 
     } 
    } 
} 

現在那些Properties將設置好的,以實例的屬性,只要GetProperties被調用。我是否認爲這是正確的方式?

回答

17

您已經創建了一個集合是這樣的:

PropertyDescriptorCollection propsCollection = 
      new PropertyDescriptorCollection(instanceProps.Cast<PropertyDescriptor>().ToArray()); 

但你只創建集合了現有的屬性,不是你的新屬性。

您需要提供從現有屬性和新屬性連接的單個數組。

事情是這樣的:

instanceProps.Cast<PropertyDescriptor>().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不僅描述了您的屬性,它還使客戶端能夠實際獲取和設置這些屬性的值。這就是整個問題,不是!

+0

'propertyType'是屬性本身的類型吧?那麼componentType呢?它是屬性所在的對象的類型? – Joao 2011-05-29 07:32:54

+0

'propertyType'是動態屬性的類型。如果你有一個名爲'Count'的動態整數屬性,它會是'typeof(int)'。 'componentType'是具有動態屬性的類的類型,例如'typeof運算(MyDynamicPropertyClass)'。 – 2011-05-29 07:37:30

+0

還有一個問題。這樣,如果以前通過'Properties'列表添加的屬性是動態訪問的(例如使用'var'),我可以確定使用'GetProperties()'來訪問所述屬性嗎? – Joao 2011-05-29 07:40:31

相關問題