2009-02-13 11 views
5

मैं एक परियोजना मैं पर काम कर रहा हूँ में निम्न कोड की तरह कुछ के साथ समाप्त हो गया का उपयोग कर। मैंने सोचा कि यह वास्तव में अजीब था कि मुझे ऐसा करने की इजाजत थी, लेकिन अब मैं आश्चर्यचकित कर रहा हूं कि मेरे हिस्से पर एक आर्किटेक्चरल गैफ की संभावना सबसे ज्यादा है।उमंग में अजीब इंटरफ़ेस बहुरूपता इंटरफ़ेस रचना

आप मेरे प्रश्न हैं:

  • वास्तव में क्या यह कहा जाता है?
  • कुछ असली दुनिया इस बात का उपयोग करता है क्या हैं?
  • क्यों किसी को भी ऐसा करने के लिए चाहेगा?

यहाँ मेरी इंटरफेस हैं:

namespace ThisAndThat 
{ 
    public class CanDoThisAndThat : ICanDoThisAndThat 
    { 
     public string Do() 
     { 
      return "I Can Do This And That!"; 
     } 

     string ICanDoThis.Do() 
     { 
      return "I Can Do This!"; 
     } 

     string ICanDoThat.Do() 
     { 
      return "I Can Do That!"; 
     } 
    } 
} 

और मेरे गुजर परीक्षण:

namespace ThisAndThat 
{ 
    public interface ICanDoThis 
    { 
     string Do(); 
    } 

    public interface ICanDoThat 
    { 
     string Do(); 
    } 

    public interface ICanDoThisAndThat : ICanDoThis, ICanDoThat 
    { 
     new string Do(); 
    } 
} 

यहाँ मेरी ठोस वर्ग है

using Xunit; 

namespace ThisAndThat.Tests 
{ 
    public class ThisAndThatTests 
    { 
     [Fact] 
     public void I_Can_Do_This_And_That() 
     { 
      ICanDoThisAndThat sut = new CanDoThisAndThat(); 

      Assert.Equal("I Can Do This And That!", sut.Do()); 
     } 

     [Fact] 
     public void I_Can_Do_This() 
     { 
      ICanDoThis sut = new CanDoThisAndThat(); 

      Assert.Equal("I Can Do This!", sut.Do()); 
     } 

     [Fact] 
     public void I_Can_Do_That() 
     { 
      ICanDoThat sut = new CanDoThisAndThat(); 

      Assert.Equal("I Can Do That!", sut.Do()); 
     } 

    } 
} 

उत्तर

5

इसमें (यह अपने उपयोगकर्ताओं के लिए भ्रमित नहीं कर रहा है प्रदान की) इस कोड के साथ कुछ भी गलत नहीं है, और यह किसी भी नाम है कि मैं से परिचित हूँ के साथ एक पद्धति नहीं है। CanDoThisAndThat दो इंटरफेस लागू करता है, इसलिए ग्राहक इसे किसी भी तरह से उपयोग कर सकते हैं।

.NET इंटरफेस को इस तरह कार्यान्वित करने की अनुमति देता है - स्पष्ट अंतरफलक कार्यान्वयन के रूप में जाना जाता है।

स्पष्ट इंटरफेस कार्यान्वयन उपयोगी होता है जब:

  1. दो इंटरफेस एक ही सदस्य परिभाषा
  2. है तुम एक इंटरफ़ेस को लागू करने की जरूरत है, लेकिन प्रचार के लिए है कि एक विशेष सदस्य ग्राहक कोड के लिए उपलब्ध है नहीं करना चाहती है कि इंटरफ़ेस प्रकार

.NET ढांचे से केस 2 का एक उदाहरण ICollection.SyncLock का उपयोग कर संदर्भ घोषित नहीं किया है।List<T>ICollection लागू करता है अभी तक निम्नलिखित कोड संकलन नहीं करेगा क्योंकि सदस्य जानबूझकर किया गया बीसीएल के डिजाइनर के रूप में नहीं रह गया है इस तरह से संग्रह ताला लगा की वकालत 'छुपा' है:

List<object> list = new List<object>(); 

lock (list.SyncRoot) // compiler fails here 
{ 
    // ... 
} 

इस प्रारूप के किसी भी विरासत कोड अभी भी काम करेगा , संदर्भ प्रकार ICollection स्पष्ट रूप से है क्योंकि:

ICollection list = new List<object>(); 

lock (list.SyncRoot) // no problem 
{ 
    // ... 
} 
+0

धन्यवाद, आप जवाब देने क्योंकि आप का सही नाम क्या हो रहा है प्रदान की है। –

+0

डाउनवॉटेड क्योंकि आपको अपने उत्तर में बहुत सारी त्रुटियां मिली हैं। सबसे पहले, कक्षा 'CanDoThisAndThat' तीन इंटरफेस लागू करता है, दो नहीं। 'आईसीनडोथिस एंड थैट' कहता है कि, जब लागू होता है, तो आपको दो अन्य इंटरफेस भी लागू करना होगा। साथ ही, सिंक्रूट को उपयोग को हतोत्साहित करने के लिए इसे छिपाने के लिए इम्प्लेमेनेशंस द्वारा स्पष्ट रूप से परिभाषित नहीं किया जाता है, आमतौर पर इसे साइट से बाहर शायद ही कभी इस्तेमाल किए जाने वाले सदस्यों को रखने के लिए किया जाता है, या यदि तथ्य यह है कि एक इंटरफ़ेस लागू किया गया है तो इससे कोई फर्क नहीं पड़ता। Http://msdn.microsoft.com/en-us/library/system.collections.icollection.syncroot.aspx और http://msdn.microsoft.com/en-us/library/bb356596.aspx पर देखें। – Andy

+0

कोई दस्तावेज उस दस्तावेज़ में कहता है कि आपको सिंकलॉक का उपयोग नहीं करना चाहिए, न ही उन्हें अप्रचलित के रूप में चिह्नित किया जाना चाहिए, जो वास्तव में किया जाता है जब कुछ अब उपयोग नहीं किया जाना चाहिए। – Andy

4

प्रत्येक प्रकार है एक interface mapping (जो कर सकते हैं यदि आप वा Type.GetInterfaceMap के साथ पुनर्प्राप्त किया जाए प्रतिबिंब के साथ इसे देखने के लिए एनटी)। यह मूल रूप से कहता है, "जब इंटरफ़ेस वाई पर विधि एक्स को बुलाया जाता है, तो यह विधि जेड कॉल करने वाला एक है।" ध्यान दें कि भले ही यह सी # में समर्थित नहीं है, मैपिंग लक्ष्य विधि के लिए इंटरफ़ेस विधि नाम से अलग नाम होना संभव है! (वीबी स्पष्ट रूप से इस का समर्थन करता है, मेरा मानना ​​है।) आपके मामले में

, आप तीन तरीकों और तीन तरीकों में से प्रत्येक शामिल इंटरफेस में से एक में एक विधि से मेल खाती है।

जब कंपाइलर किसी इंटरफ़ेस के माध्यम से वर्चुअल विधि पर कॉल जारी करता है, तो आईएल उत्पन्न होता है "इस ऑब्जेक्ट पर IFoo.Bar को कॉल करें" - और IFoo.Bar को इंटरफ़ेस मानचित्र का उपयोग करके हल किया जाता है।

आपको कभी-कभी इसका उपयोग करने की आवश्यकता हो सकती है यदि आपके पास हस्ताक्षर हैं जो केवल रिटर्न प्रकार में भिन्न हैं, या यदि आप दो विषम इंटरफेस को कार्यान्वित कर रहे हैं जो समान विधि नाम होते हैं लेकिन अलग-अलग चीजें करना चाहिए। जहां भी आप से बच सकते हैं, हालांकि! यह बहुत भ्रमित कोड के लिए बनाता है।

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