2013-06-18 9 views
5

पर इंटरफ़ेस को कई बार परिभाषित करना I अनिवार्य रूप से IFoo को विरासत कक्षा में दो बार परिभाषित करता है। क्या इससे कुछ अप्रत्याशित परिणाम निकलते हैं?विरासत वर्ग

interface IFoo { 
    ... 
} 

interface IBar : IFoo { 
    ... 
} 

class Base : IFoo { 
    ... 
} 

class Derived : Base, IBar { 
    ... 
} 

कारण मैं IFoo से IBar इनहेरिट बनाना चाहते तो मैं Derived पर काम कर सकते के रूप में यह यह कास्ट करने के लिए बिना IFoo था।

if (Derived is IBar) 
    // Do work 

यदि यह वारिस नहीं है तो मुझे इसे कास्ट करना होगा। जो अधिक जटिल उपयोग करता है, और कक्षा के उपयोगकर्ता यह समझ नहीं सकते कि IBar सिर्फ IFoo का एक विशेषज्ञ है।

if (Derived is IBar) 
    Derived as IFoo 
    // Do work 

क्या यह बुरा अभ्यास है? इस समस्या के लिए अन्य समाधान क्या हैं?

+0

आप क्यों करना चाहते हैं 'अगर (आईबीआर व्युत्पन्न है) IFoo' के रूप में व्युत्पन्न? क्यों नहीं 'अगर (व्युत्पन्न IFoo है)' क्यों? –

+0

क्योंकि आईबार एक मार्कर इंटरफेस है जो मुझे बताता है कि 'व्युत्पन्न' एक विशिष्ट प्रकार का है। इस तरह मैं सभी IFoo को संग्रह में रख सकता हूं और उन सभी के साथ काम कर सकता हूं। मुझे आईबीआर प्रकारों पर केवल "काम करना" चाहिए, जो मैं कर सकता हूं। ओएफटी टाइप । –

उत्तर

5

यह कोड शर्तों में किसी भी अप्रत्याशित परिस्थितियों का कारण नहीं बनता है। यह सिर्फ अनावश्यक है।

इस कोड के लिए के रूप में:

if (Derived is IBar) 
    Derived as IFoo 

कि पूरी तरह से अनावश्यक है के बाद से Derived एक IFoo है, अपने घोषणाओं दिया - ताकि मत करो!

ध्यान दें कि IBarIFoo से प्राप्त नहीं होता है, तो आपको अभी भी Derived as IFoo की आवश्यकता नहीं है। यह देखते हुए:

interface IFoo {} 

interface IBar {} 

class Base : IFoo {} 

class Derived : Base, IBar 
{ 
} 

तो यह ठीक संकलित:

var derived = new Derived(); 

IBar bar = derived; // Fine. 
IFoo foo = derived; // Also fine. 
+0

'आईफू के रूप में व्युत्पन्न' का एक उदाहरण था, यदि मुझे 'आईफू' –

+0

@ Snæbjørn से प्राप्त नहीं हुआ था, लेकिन यह सच नहीं है - भले ही 'आईबार' 'IFoo' से प्राप्त न हो, ' बेस' पहले से ही ऐसा करता है इसलिए आपको 'IFoo' के रूप में व्युत्पन्न की आवश्यकता नहीं है। मेरा अद्यतन उत्तर देखें। –

+0

आह हाँ, यह सही है। मुझे एहसास हो रहा है कि मैंने समस्या को सही तरीके से समझाया नहीं है :(। आपका सुझाव यह है कि मैं सामान्य रूप से कैसे करता हूं, और शायद मुझे यह करना चाहिए। यह शायद एक और पोस्ट होना चाहिए, लेकिन यहां जाता है। मैं दोनों को संग्रहीत कर रहा हूं 'सूची ' में बेस और व्युत्पन्न। मैं सूची से सभी 'इबार' निकालना चाहता हूं। यह मैं 'list.OfType ' का उपयोग कर रहा हूं। समस्या यह है कि मैं उस सूची को 'सूची ' में उपयोग किए बिना स्टोर नहीं कर सकता '.स्ट 'जो अनजान है। मुझे अपने डिजाइन पर संदेह करना शुरू हो रहा है :) –

1

आप स्पष्ट रूप से एक Interface के लिए एक कार्यान्वयन परिभाषित कर सकते हैं और इतना है कि से

class Derived : Base, IBar { 

    void IBar.Method(){ 

    } 

    void Base.Method() { 

    } 
} 

अलावा व्यवहार में भेद, आप कर सकते हैं कि , लेकिन यह अनावश्यक है और भ्रम पैदा कर सकता है। MSDN देखें।

+0

क्या यह भी कानूनी वाक्यविन्यास है? –

+0

मैं 'ओवरराइड' के बारे में गलत था, एमएसडीएन-लेख कहता है कि आप ऐसा कर सकते हैं। वीएस इस सुविधा को भी प्रदान करता है –

+0

मुझे लगता है कि विधियां 'निजी' होनी चाहिए, तो आप –

1

यदि मैं आपको सही ढंग से समझता हूं, तो आपके पास इंटरफेस का एक पदानुक्रम और एक-दूसरे के प्रतिबिंबित वर्गों का एक पदानुक्रम है। प्रत्येक वर्ग इसके बेस क्लास से विरासत में प्राप्त होने और आवश्यक अतिरिक्त सदस्यों को लागू करके संबंधित इंटरफ़ेस लागू करता है।

यह ठीक है और मैं वही करता हूं। मुझे ऐसा करने का कोई बेहतर तरीका नहीं पता - यह एक अच्छा दृष्टिकोण है।

मुझे लगता है कि आईबार को आपके मुख्य सुझाव की तरह आईफू का विस्तार करना चाहिए, अन्यथा उपभोक्ताओं को बहुत कुछ डालना होगा। इसके अलावा, जब से आप आईबार को एक विशेषज्ञता IFoo मानते हैं, इसे कोड में विशेषज्ञता बनाते हैं, इसलिए इसे IFoo का विस्तार करें।

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