2015-09-25 6 views
6

नीचे दिए गए उदाहरण में, कार्यान्वयन वर्ग की विधि के लिए एक तरीका है जो स्पष्ट रूप से संकलक को बताता है कि यह कौन सा इंटरफ़ेस सदस्य लागू करता है? मुझे पता है इंटरफेस के बीच अस्पष्टता को हल करना संभव है, लेकिन यहां यह एक इंटरफेस के भीतर है।अस्पष्ट इंटरफ़ेस विधि हस्ताक्षर कैसे हल करें, जब कई सामान्य प्रकार के तर्क समान होते हैं

interface IFoo<A, B> 
{ 
    void Bar(A a); 
    void Bar(B b); 
} 

class Foo : IFoo<string, string> 
{ 
    public void Bar(string a) { } 
} 

इस मामले void Bar(string a) की एक एकल कार्यान्वयन होने में इंटरफ़ेस के दोनों तरीकों को लागू करता है:

interface IFoo<A,B> 
{ 
    void Bar(A a); 
    void Bar(B b); 
} 

class Foo : IFoo<string, string> 
{ 
    public void Bar(string a) { } 
    public void Bar(string b) { } // ambiguous signature 
} 
+1

आप इंटरफेस को गलत समझ रहे हैं। आपको केवल 'सार्वजनिक शून्य बार (स्ट्रिंग ए) {} 'की आवश्यकता है। आप इंटरफ़ेस के *** अनुबंध *** को कार्यान्वित कर रहे हैं, न कि विधि परिभाषाएं स्वयं। बाहरी कॉलर को 'ए' =' बी' होने पर दो 'बार' परिभाषाओं के बीच कोई अंतर नहीं है। वे एक ही हैं। – Rob

+0

मुझे नहीं लगता कि आप इसे हल कर सकते हैं क्योंकि यदि आप जेनेरिक का उपयोग नहीं करते हैं, तो जेनिक्स के बिना लिखें और देखें कि क्या होता है, शायद यह समझने में आपकी सहायता करता है कि क्यों संभव नहीं है –

+0

आगे की व्याख्या करने के लिए, आपका इंटरफ़ेस कहता है "कोई भी जो उपकरण लागू करता है मैं 'बार (ए)' और 'बार (बी)' लागू करेगा। '' गुजरते समय, अनुबंध बन जाता है "जो भी मुझे लागू करता है वह 'बार (स्ट्रिंग)' लागू करेगा। – Rob

उत्तर

2

मुझे नहीं लगता कि आप केवल एक इंटरफ़ेस का उपयोग कर इसे हल कर सकते हैं क्योंकि विधि हस्ताक्षर कुछ मामलों के लिए एकजुट हो सकते हैं।

यदि आपको वास्तव में इस सुविधा की आवश्यकता है तो मुझे लगता है कि आपको एक नया इंटरफ़ेस पेश करना होगा जो foo द्वारा प्राप्त किया जाएगा।

public interface IBar<T> 
{ 
    void Bar(T t); 
} 

public interface IFoo<A, B> : IBar<A> 
{ 
    void Bar(B b); 
} 

अब आप स्पष्ट रूप से दोनों इंटरफेस को लागू करने में समर्थ हैं:

public class Foo : IFoo<string, string> 
{ 
    void IFoo<string, string>.Bar(string b) 
    { 
     Console.WriteLine("IFoo<string, string>.Bar: " + b); 
    } 

    void IBar<string>.Bar(string t) 
    { 
     Console.WriteLine("IBar<string>.Bar: " + t); 
    } 
} 

लेकिन आप इसे उपयोग करने के लिए आप विशेष इंटरफ़ेस करने के लिए अपने उदाहरण कास्ट करने के लिए है चाहते हैं:

var foo = new Foo(); 
((IFoo<string, string>)foo).Bar("Hello"); 
((IBar<string>foo).Bar("World"); 

यह प्रिंट अपेक्षित के रूप में:

IFoo<string, string>.Bar: Hello 
IBar<string>.Bar: World 

उम्मीद है कि यह आपकी मदद करेगा। मुझे नहीं लगता कि ऐसा करने का एक और तरीका है।

स्पष्ट रूप से केवल एक इंटरफ़ेस को लागू करना संभव है ताकि आपको केवल अन्य विधि को कॉल करना है या नहीं।

+0

धन्यवाद। इंटरफ़ेस को बदलना महंगा है और मैंने इसे टालने का प्रयास किया, लेकिन ऐसा लगता है कि इसके चारों ओर कोई रास्ता नहीं है। मैं विधि नाम को बारए और बारबी में बदल दूंगा। –

1

तुम बस डुप्लिकेट लाइन को हटाने के लिए की जरूरत है।

असल में इंटरफ़ेस को कॉल करना बहुत कठिन है। आपको प्रतिबिंब की आवश्यकता है।

+0

धन्यवाद। यह कोड संकलित करता है, लेकिन यह समस्या को हल नहीं करता है। 'बार (ए)' और 'बार (बी)' अर्थात् अलग हैं और इस प्रकार एक ही विधि द्वारा लागू नहीं किया जा सकता है। यदि अस्पष्टता को हल करने का कोई तरीका नहीं है, तो मुझे विधि नाम बदलना होगा। –

+0

@ArmyNoodles - हाँ, यही वह है जो आपको करना होगा। – Enigmativity

0

आप ऐसा नहीं कर सकते हैं।

Bar() इस स्थिति में अस्पष्ट होगा। BarA(), BarB() पर इंटरफ़ेस विधियों को बदलने पर विचार करें।

इसके अलावा, A और B अधिक सार्थक नाम (उदाहरण के लिए, IFoo<TKey, TValue>), तो अपने तरीके BarKey() और BarValue() हो सकता है पर विचार करें।

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