2017-02-15 6 views
5

निम्नलिखित इंटरफेस पर विचार करें:एक सामान्य इंटरफ़ेस को लागू नई बाधा लापता

public interface IFoo 
{ 
    M Bar<M>(); 
} 

कि लागू करने के लिए

class Foo : IFoo 
{ 
    public M Bar<M>() 
    { 
     return new M(); 
    } 
} 

साथ काम नहीं करता कोशिश कर रहा है, संकलक शिकायत M एक new() बाधा याद आ रही है।

जब मैं

class Foo : IFoo 
{ 
    public M Bar<M>() where M : new() 
    { 
     return new M(); 
    } 
} 

यह अभी भी में के रूप में बाधा जोड़ने चाल नहीं करता है, के रूप में Foo.Bar की कमी अब इंटरफ़ेस विधि की कमी से मेल नहीं खाते (और मैं बदलने में सक्षम नहीं कर रहा हूँ उस)।

documentation for the compiler error CS0425

इस त्रुटि से बचने, यकीन है कि जहां खंड दोनों घोषणाओं में समान होता है बनाने के लिए, या इंटरफ़ेस स्पष्ट रूप से लागू करने के लिए कहते हैं।

यदि "इंटरफ़ेस को स्पष्ट रूप से कार्यान्वित करना" समाधान है: मैं इसे कैसे कर सकता हूं?

+0

ऐसा इसलिए है क्योंकि आपको एक नया वापस करने की आवश्यकता है या आपको कुछ वापस करने की आवश्यकता है जब वापस लौटने के लिए कुछ और नहीं है? क्या डिफ़ॉल्ट (एम) 'पर्याप्त होगा? यह दिए गए जेनेरिक प्रकार के लिए डिफ़ॉल्ट मान देता है, संदर्भों के लिए यह 'शून्य' है। अन्यथा आपको अपना उदाहरण बनाने के लिए अभिव्यक्ति पेड़ या प्रतिबिंब की आवश्यकता होगी। –

उत्तर

6

आप इंटरफ़ेस परिभाषा को बदल नहीं सकते हैं, तो आप new M(); का उपयोग कर से बचने के लिए होगा - बजाय Activator.CreateInstance का उपयोग करें:

class Foo : IFoo 
{ 
    public M Bar<M>() 
    { 
     return Activator.CreateInstance<M>(); 
    } 
} 
बेशक

, अब आप एक रनटाइम त्रुटि में पड़ सकते हैं वहाँ अगर कोई parameterless निर्माता M के लिए, लेकिन यह अपरिहार्य है (फिर से, क्योंकि हम सामान्य बाधाओं को नहीं बदल सकते हैं)।


पुन: प्रलेखन:

स्पष्ट इंटरफ़ेस को लागू।

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

+0

दस्तावेज़ीकरण की व्याख्या करने के लिए धन्यवाद: आप शायद सही हैं। मैं सोचने के तरीके में था "दस्तावेज बताता है कि मैंने क्या गलत किया है और दुर्दशा से बाहर निकलने का तरीका दिखाता है", जिसने मुझे गलत रास्ते पर ले जाया। – mkluwe

0

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

5

इंटरफ़ेस को कार्यान्वित करना स्पष्ट रूप से समाधान नहीं है। कंपाइलर बस आपको बता रहा है कि यदि आपको उस बाधा के साथ Bar की सामान्य विधि की आवश्यकता है, तो Bar दोनों संस्करणों को सह-अस्तित्व में रख सकते हैं, लेकिन जाहिर है, समाधान नहीं है कि आप इसके लिए देख रहे हैं।

केवल समाधान हैं:

  1. लागू इंटरफ़ेस में सामान्य प्रकार बाधा।
  2. प्रतिबिंब के माध्यम से नए M को तत्काल करें: Activator.CreateInstance और संकलन समय पर खोने वाली सुरक्षा की कीमत का भुगतान करें; पैरामीटर रहित कन्स्ट्रक्टर रखने के लिए कुछ भी M लागू नहीं करता है।
+0

कुछ भी लागू नहीं कर रहा है कि 'एम' एक ऐसा प्रकार भी है जिसे आप तुरंत चालू कर सकते हैं, एक इंटरफ़ेस हो सकता है। –

+0

@AdamHouldsworth ठीक है, किसी भी गैर तत्काल प्रकार में उपयोग करने योग्य पैरामीटर रहित कन्स्ट्रक्टर की कमी है। मैं उस अंतर को देखने में असफल हूं जिसे आप बनाने की कोशिश कर रहे हैं। – InBetween

+0

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

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