क्लास को लागू करने पर इंटरफ़ेस पर परिभाषित C # 4 वैकल्पिक पैरामीटर क्यों लागू नहीं किए गए हैं?


361

मैं सी # 4 में वैकल्पिक पैरामीटर के साथ कि देखा है अगर आप एक अंतरफलक आप पर एक वैकल्पिक पैरामीटर निर्दिष्ट डॉन, टी किसी भी लागू करने वर्ग पर कि पैरामीटर वैकल्पिक बनाने के लिए है:

public interface MyInterface
{
    void TestMethod(bool flag = false);
}

public class MyClass : MyInterface
{
    public void TestMethod(bool flag)
    {
        Console.WriteLine(flag);
    }
}

और इसीलिए:

var obj = new MyClass();        
obj.TestMethod(); // compiler error

var obj2 = new MyClass() as MyInterface;
obj2.TestMethod(); // prints false

क्या किसी को पता है कि वैकल्पिक मापदंडों को इस तरह से काम करने के लिए क्यों बनाया गया है?

एक तरफ मुझे लगता है कि इंटरफेस पर निर्दिष्ट किसी भी डिफ़ॉल्ट मान को ओवरराइड करने की क्षमता उपयोगी है, हालांकि ईमानदार होना मुझे यकीन नहीं है अगर आपको इंटरफ़ेस पर डिफ़ॉल्ट मानों को निर्दिष्ट करने में सक्षम होना चाहिए क्योंकि यह एक कार्यान्वयन निर्णय होना चाहिए।

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


22
क्योंकि वे वैकल्पिक हैं?
ओड

1
लेकिन आप ऑब्जेक्ट उदाहरण को MyInterfaceवैकल्पिक पैरामीटर के साथ कॉल और कॉल कर सकते हैं ((MyInterface)obj).TestMethod();:।
जिम मेंथेल

7
@ कूट - लेकिन अगर आप कहते हैं कि यह पैरामीटर अनुबंध पर वैकल्पिक है, तो आप कार्यान्वयनकर्ता को इसे वैकल्पिक क्यों नहीं बनाने देंगे? अनुबंध का उपयोग करने के लिए किसी को भ्रम की स्थिति पैदा नहीं करता है?
15

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

2
अधिक विस्तार से समस्या की व्याख्या यहाँ -> geekswithblogs.net/BlackRabbitCoder/archive/2010/06/17/…
एंड्रयू ऑरिच

जवाबों:


235

UPDATE: यह प्रश्न १२ मई २०११ को मेरे ब्लॉग का विषय था। महान प्रश्न के लिए धन्यवाद!

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

मान लीजिए हमने ऐसा किया। अब मान लीजिए कि डेवलपर के पास कार्यान्वयन के लिए स्रोत कोड नहीं था:


// in metadata:
public class B 
{ 
    public void TestMethod(bool b) {}
}

// in source code
interface MyInterface 
{ 
    void TestMethod(bool b = false); 
}
class D : B, MyInterface {}
// Legal because D's base class has a public method 
// that implements the interface method

डी के लेखक को यह काम कैसे करना चाहिए? क्या उन्हें आपकी दुनिया में फोन पर बी के लेखक को फोन करने की आवश्यकता है और कृपया उन्हें बी के एक नए संस्करण को जहाज करने के लिए कहें, जिससे विधि का एक वैकल्पिक पैरामीटर हो?

वह उड़ने वाला नहीं है। क्या होगा अगर दो लोग बी के लेखक को बुलाते हैं, और उनमें से एक डिफ़ॉल्ट को सच करना चाहता है और उनमें से एक यह चाहता है कि यह गलत हो? क्या होगा यदि B का लेखक बस साथ निभाने से इंकार कर दे?

शायद उस मामले में उन्हें कहना आवश्यक होगा:

class D : B, MyInterface 
{
    public new void TestMethod(bool b = false)
    {
        base.TestMethod(b);
    }
}

प्रस्तावित सुविधा प्रोग्रामर के लिए प्रतिनिधि शक्ति में कोई इसी वृद्धि के साथ असुविधा को जोड़ने के लिए लगता है। इस सुविधा का अनिवार्य लाभ क्या है जो उपयोगकर्ता के लिए बढ़ी हुई लागत को सही ठहराता है?


अद्यतन: नीचे दी गई टिप्पणियों में, सुपरकैट एक भाषा सुविधा का सुझाव देता है जो वास्तव में भाषा में शक्ति जोड़ देगा और इस प्रश्न में वर्णित एक के समान कुछ परिदृश्यों को सक्षम करेगा। FYI करें, वह सुविधा - इंटरफेस में विधियों का डिफ़ॉल्ट कार्यान्वयन - C # 8 में जोड़ा जाएगा।


9
@ सुपरकैट: हमारे पास ऐसा करने की कोई योजना नहीं है, लेकिन इस तरह की सुविधा संभव है। यह पहले प्रस्तावित किया गया है। C # 4 के लिए डिज़ाइन की प्रक्रिया के दौरान हमने "एक्सटेंशन सब कुछ" सुविधाओं को बहुत कुछ कहा है - हमारे पास एक्सटेंशन विधियां हैं, इसलिए एक्सटेंशन इवेंट्स, एक्सटेंशन प्रॉपर्टीज, एक्सटेंशन कंस्ट्रक्टर, एक्सटेंशन इंटरफेस और इतने पर इसका क्या मतलब होगा । कक्षाएं जो आप इंटरफेस को "संलग्न" कर सकते हैं और कह सकते हैं कि "ये तरीके इस इंटरफ़ेस के डिफ़ॉल्ट कार्यान्वयन हैं" "विस्तार इंटरफेस" को चिह्नित करने का एक संभव तरीका है। एक दिलचस्प विचार।
एरिक लिपर्ट

16
मेरे तर्क को स्पष्ट करने के लिए कि मुझे क्यों लगता है कि यह गैर-सहज है: मेरे लिए एक वैकल्पिक पैरामीटर "इंटरफ़ेस के कार्यान्वयनकर्ता के लिए वैकल्पिक नहीं" विधि के कॉलर के लिए वैकल्पिक है "।
स्टीफन डी कोक

8
"क्या वे आपकी दुनिया में फोन पर बी के लेखक को फोन करने और उन्हें एक नया संस्करण प्रदान करने के लिए कहेंगे [...]?" नहीं, कोई फ़ोन कॉल की आवश्यकता नहीं है। बी को अब केवल MyInterface का एक अनुमान नहीं माना जा सकता है और डी के लेखक को संकलक द्वारा इसके बारे में अवगत कराया जा सकता है। D के लेखक को एक TestMethod के साथ D को लागू करने की आवश्यकता होगी जो कि एक डिफ़ॉल्ट पैरामीटर को स्वीकार करता है क्योंकि इंटरफ़ेस लेखक की आवश्यकता है - आप इंटरफ़ेस लेखक को एक बाधा को लागू करने की अनुमति देने के खिलाफ बहस कर रहे हैं क्योंकि कोई इसे तोड़ना चाहता हो सकता है। यह एक अच्छा तर्क नहीं है।
फिलोफिनफिनजेस्ट

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

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

47

एक वैकल्पिक पैरामीटर को केवल एक विशेषता के साथ टैग किया जाता है। यह विशेषता कॉल-साइट पर उस पैरामीटर के लिए डिफ़ॉल्ट मान सम्मिलित करने के लिए कंपाइलर को बताती है।

कॉल obj2.TestMethod();को obj2.TestMethod(false);तब बदल दिया जाता है जब C # कोड IL पर संकलित हो जाता है, न कि JIT-time पर।

तो एक तरह से यह हमेशा वैकल्पिक मापदंडों के साथ डिफ़ॉल्ट मान प्रदान करने वाला कॉलर है। बाइनरी वर्जनिंग पर इसके परिणाम भी होते हैं: यदि आप डिफ़ॉल्ट मान को बदलते हैं, लेकिन कॉलिंग कोड को फिर से जमा नहीं करते हैं तो यह पुराने डिफ़ॉल्ट मान का उपयोग करना जारी रखेगा।

दूसरी ओर, इस डिस्कनेक्ट का मतलब है कि आप हमेशा ठोस वर्ग और इंटरफ़ेस का उपयोग नहीं कर सकते।

आप पहले से ही ऐसा नहीं कर सकते हैं यदि इंटरफ़ेस विधि स्पष्ट रूप से लागू की गई थी ।


1
क्या आप कार्यान्वयनकर्ताओं को स्पष्ट रूप से लागू करने के लिए बाध्य कर सकते हैं?
क्रश करें

30

क्योंकि डिफ़ॉल्ट पैरामीटर को संकलित समय पर हल किया जाता है, न कि रनटाइम पर। इसलिए डिफ़ॉल्ट मानों को कॉल की जा रही वस्तु से संबंधित नहीं है, लेकिन संदर्भ प्रकार के माध्यम से जिसे यह कहा जा रहा है।


7

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

हमारी साइट का प्रयोग करके, आप स्वीकार करते हैं कि आपने हमारी Cookie Policy और निजता नीति को पढ़ और समझा लिया है।
Licensed under cc by-sa 3.0 with attribution required.