2011-11-04 14 views
8

सी # का उपयोग करते हुए मेरे पास एक कक्षा है जिसमें अन्य मेटा जानकारी के बीच निर्देशित ग्राफ़ की रूट नोड शामिल है। आइए इसे कंटेनर-क्लास पर कॉल करें। यह कंटेनर दो अलग-अलग मोड, संपादक-मोड और कॉन्फ़िगरेटर-मोड में दिखाई दे सकता है। मोड के आधार पर, रूट-नोड एक अलग प्रकार के NodeEdit या नोडकॉन्फिग, दोनों एक ही उप-वर्ग से विरासत में है।विरासत वाली संपत्ति के प्रकार को बदलना (विरासत प्रकार के लिए)

public abstract class NodeBase 
{ 
    string Name { get; set; } 
    ... 
} 

public class NodeEdit : NodeBase ... 
public class NodeConfig : NodeBase ... 

कंटेनर के लिए, मैं भी एक आधार वर्ग बनाने और इसे से विरासत:

public abstract class ContainerBase 
{ 
    NodeBase Root { get; set; } 
    ... 
} 

जब ContainerBase से इनहेरिट द्वारा संपादक और Configuratorcontainer के लिए कक्षाओं का निर्माण, मैं के प्रकार बनना चाहते हैं रूट - संपत्ति विशिष्ट (NodeBase से विरासत में मिली) की तरह टाइप करें:

public class ContainerEditor : ContainerBase 
{ 
    NodeEditor Root { get; set; } 
    ... 
} 

लेकिन मैं एक संपत्ति ContainerBase में परिभाषित के प्रकार नहीं बदल सकते। क्या इस समस्या को हल करने का कोई तरीका है? मैं BaseNode प्रकार उपयोग कर सकते हैं, और

ContainerEditorInstance.Root = new NodeEditor(); 

तरह NodeEditor का एक तत्व जोड़ने क्योंकि प्रकार NodeEditor प्रकार BaseEditor से विरासत में मिली है, लेकिन कंटेनर-संपादक कक्षा में, मैं स्पष्ट रूप से केवल के प्रकार की अनुमति देना चाहते रूट-प्रॉपर्टी नोड एडिटर है। मैं इसे सेटटर में देख सकता हूं और सभी नोड्स को अस्वीकार कर सकता हूं लेकिन टाइप नोडीडिटर के प्रकार, लेकिन मैं संपत्ति को विशिष्ट प्रकार का होना चाहता हूं, इसलिए मैं संकलन समय पर गलत असाइनमेंट का पता लगा सकता हूं।

अग्रिम धन्यवाद,
फ्रैंक

उत्तर

4

आप इसे redeclare कर सकते हैं::

public class ContainerEditor : ContainerBase 
{ 
    public NodeEditor Root { 
    get { return (NodeEditor)base.Root; } 
    set { base.Root = value; } 
    } 
    ... 
} 
+0

हाय मार्क, उत्तर के लिए धन्यवाद! मैंने पहले ही इसे पुनर्विक्रय के साथ आजमाया था, लेकिन शायद मैंने कुछ गलत किया था। मैंने आपके दृष्टिकोण का परीक्षण किया और यह ठीक काम करता है! आम तौर पर, ऐसी स्थितियां हैं जहां जेनिक्स या वीका के विपरीत पुनर्विक्रय को प्राथमिकता दी जानी चाहिए या वे बराबर हैं? – Aaginor

+0

यह पूरी जेनेरिक चीजें गंभीर समस्याएं पैदा कर रही हैं जब जेनेरिक बेस क्लास का उपयोग किया जाना चाहिए यानी एक सार वापसी के रूप में।तो मैं एक शॉट फिर से शुरू कर दूंगा, क्योंकि यह कम घुसपैठिया प्रतीत होता है। 'नया' और 'ओवरराइड' की तुलना में, आंतरिक रूप से काम करने का पुनर्विक्रय कैसे किया जा रहा है? क्या इसके बारे में कोई अच्छा लेख है जो आप सिफारिश कर सकते हैं? एक बार फिर धन्यवाद! – Aaginor

9

उपयोग जेनरिक:

public abstract class ContainerBase<TRoot> where TRoot : NodeBase 
{ 
    TRoot Root { get; set; } 
    ... 
} 

व्युत्पन्न वर्ग में आप प्रकार निर्दिष्ट:

public abstract class ContainerBase<T> where T:NodeBase 
{ 
    T Root { get; set; } 
    ... 
} 

public class ContainerEditor : ContainerBase<NodeEditor> 
{  
    ... 
} 
+0

हाय Blau, हमेशा की तरह HashSet और इसी तरह के उपयोग के बगल में जेनरिक के साथ कभी नहीं निपटा तो तुम कुछ इस तरह लिखना चाहते हैं। सोचो कि यह शायद उनके साथ काम करने का एक अच्छा समय होगा! – Aaginor

1

आप कंटेनर आधार सामान्य बना सकते हैं

public class ContainerEditor : ContainerBase<NodeEditor> 
{ 
    ... 
} 
+0

अच्छा विचार, मैं इसे एक शॉट दूंगा। – Aaginor

0

मुझे लगता है कि यहां एक अच्छा समाधान जेनेरिक होगा।

public class ContainerEditor<T>:ContainerBase 
{ 
    T Root {get;set;} 
} 
+0

मुझे कंटेनरबेस में रूट को उन कार्यों में एक्सेस करने में सक्षम होने की आवश्यकता होगी जिन्हें संपादक या कॉन्फ़िगरेटर को पहिया जानने की आवश्यकता नहीं है। वैसे भी जेनेरिक एक अच्छा विचार की तरह लगता है, जैसे गुफा और ब्लौ ने दिखाया। – Aaginor

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