2011-05-29 16 views
13

मेरे पास एक कक्षा है जो प्रोग्रामर गतिशील रूप से नई गुणों को जोड़ने के लिए उपयोग कर सकता है। इसके लिए यह GetProperties() विधि को ओवरराइड करने में सक्षम होने के लिए ICustomTypeDescriptor लागू करता है।रनटाइम पर गुण जोड़ें

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 
     } 
    } 
} 

जब भी GetProperties कहा जाता है अब उन Properties उदाहरण गुणों के setted किया जाएगा। क्या मैं इसे सही तरीके से सोच रहा हूं?

उत्तर

17

आप पहले से ही इस तरह एक संग्रह का निर्माण कर रहे:

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

लेकिन संग्रह आप केवल पैदा कर रहे मौजूदा गुण, नहीं अपने नए गुण है।

आपको मौजूदा गुणों और अपनी नई संपत्तियों से जुड़ी एक एकल सरणी की आपूर्ति करने की आवश्यकता है।

कुछ इस तरह:

instanceProps.Cast<PropertyDescriptor>().Concat(customProperties).ToArray() 

अगला समस्या: आप customProperties जरूरत है जो PropertyDescriptor का एक संग्रह है। दुर्भाग्यवश PropertyDescriptor एक सार वर्ग है इसलिए आपके पास एक बनाने का आसान तरीका नहीं है।

हम इसे ठीक कर सकते हैं, बस कक्षा को PropertyDescriptor से प्राप्त करके और सभी अमूर्त तरीकों को लागू करके परिभाषित करें।

कुछ इस तरह:

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' संपत्ति का प्रकार सही है? घटक टाइप के बारे में क्या? क्या यह उस वस्तु का प्रकार है जहां संपत्ति बैठती है? – Joao

+0

'propertyType' गतिशील संपत्ति का प्रकार है। यदि आपके पास 'गणना' नामक एक गतिशील पूर्णांक संपत्ति है, तो यह 'टाइपऑफ (int) 'होगी। 'घटक प्रकार' उस वर्ग का प्रकार है जिसमें गतिशील गुण हैं, उदा। 'Typeof (MyDynamicPropertyClass)'। –

+0

बस एक और सवाल। इस तरह यदि किसी संपत्ति को पहले 'गुण' सूची के माध्यम से जोड़ा गया है, तो गतिशील रूप से उपयोग किया जाता है (उदाहरण के लिए 'var' का उपयोग करके) क्या मैं सुनिश्चित कर सकता हूं कि' प्रॉपर्टी एक्सेस ') का उपयोग उस संपत्ति तक पहुंचने के लिए किया जाता है? – Joao

संबंधित मुद्दे