2010-04-02 21 views
55

सी # 4.0 का उपयोग करना - एक इंटरफ़ेस बनाना और इंटरफ़ेस लागू करने वाली कक्षा। मैं इंटरफेस में एक वैकल्पिक पैरामीटर घोषित करना चाहता हूं और इसे कक्षा में प्रतिबिंबित करना चाहता हूं। तो, मेरे पास निम्न है:इंटरफेस के लिए वैकल्पिक पैरामीटर

public interface IFoo 
{ 
     void Bar(int i, int j=0); 
} 

public class Foo 
{ 
     void Bar(int i, int j=0) { // do stuff } 
} 

यह संकलित करता है, लेकिन यह सही नहीं दिखता है। इंटरफ़ेस में वैकल्पिक पैरामीटर होना आवश्यक है, अन्यथा यह इंटरफ़ेस विधि हस्ताक्षर में सही ढंग से प्रतिबिंबित नहीं होता है।

क्या मुझे वैकल्पिक पैरामीटर छोड़ना चाहिए और केवल एक शून्य प्रकार का उपयोग करना चाहिए? या यह कोई दुष्प्रभाव या परिणामों के इरादे से काम करेगा?

+2

नीचे मार्टिन की टिप्पणियां विभिन्न नुकसान का एक विस्तृत उदाहरण देती हैं, और मेरी इच्छा है कि संकलक गैर मिलान वाले डिफ़ॉल्ट तर्कों को ध्वजांकित करेगा। उस ने कहा, मैं इसे अपने कोड में उपयोग कर रहा हूं क्योंकि यह अन्य डेवलपर्स के लिए इंटरफ़ेस और कार्यान्वयन स्तर दोनों पर डेवलपर के रूप में मेरा इरादा इंगित करता है। –

+0

दिलचस्प संबंधित प्रश्न, "[क्या इंटरफेस में वैकल्पिक पैरामीटर घोषित करने का कोई कारण है?] (Https: // stackoverflow।कॉम/प्रश्न/6752762 /) ", और," [इंटरफ़ेस पर परिभाषित सी # 4 वैकल्पिक पैरामीटर क्यों कक्षा लागू करने पर लागू नहीं हैं?] (https://stackoverflow.com/questions/4922714/) ", दूसरा दिलचस्प है [लिपर्ट से जवाब] (https://stackoverflow.com/a/4923642/1028230) – ruffin

उत्तर

28

आप पूर्व वैकल्पिक-पैरामीटर विकल्प पर विचार कर सकते:

public interface IFoo 
{ 
    void Bar(int i, int j); 
} 

public static class FooOptionalExtensions 
{ 
    public static void Bar(this IFoo foo, int i) 
    { 
     foo.Bar(i, 0); 
    } 
} 

आप एक नई भाषा की सुविधा के रूप को पसंद नहीं है, तो आप इसका इस्तेमाल करने की जरूरत नहीं है।

+40

लेकिन ... यह नया है! और चमकदार! :-) – bryanjonker

+1

यह कैसे काम करता है, या शायद एक अतिरिक्त स्पष्टीकरण प्रदान करने के लिए स्वतंत्र महसूस करें जो आप "प्री-वैकल्पिक-पेरेमेटर्स विकल्प" के रूप में संदर्भित कर रहे हैं उससे लिंक करें। भविष्य में उपयोगकर्ताओं की मदद कर सकते हैं!:] –

+0

बेशक ऐसा करने का वास्तव में पुराना तरीका (पूर्व सी # 3 विस्तार विधियों को पेश करना) दोनों में विधि अधिभार का उपयोग करना था कक्षा और इंटरफ़ेस। यदि आपके पास क्लास कोड ओवरलोडिंग तक पहुंच है तो शायद एक एक्सटेंशन विधि से बेहतर है क्योंकि यह कोड को एक ही स्थान पर रखता है। –

1

एक तरफ दिखता है, यह वही करेगा जो आपको लगता है कि आप इसे पूरा करना चाहते हैं।

+2

यह प्रश्न का उत्तर नहीं देता है। लेखक से स्पष्टीकरण की आलोचना या अनुरोध करने के लिए , एक कॉम छोड़ दो उनके पद के नीचे एनटी। –

+3

मुझे नहीं पता। ऐसा लगता है कि यह सवाल पूछने का सीधा जवाब है: "या यह काम किसी दुष्प्रभाव या परिणामों के इरादे से नहीं होगा?" – MojoFilter

3

इस तरह कुछ के बारे में क्या?

public interface IFoo 
{ 
    void Bar(int i, int j); 
} 

public static class IFooExtensions 
{ 
    public static void Baz(this IFoo foo, int i, int j = 0) 
    { 
     foo.Bar(i, j); 
    } 
} 

public class Foo 
{ 
    void Bar(int i, int j) { /* do stuff */ } 
} 
+0

@Iznogood - यहां संपादित किया गया संपादन स्पष्ट रूप से मान्य संपादन नहीं है: http://stackoverflow.com/review/suggested-edits/1041521। संपादन की समीक्षा करते समय कृपया अधिक सावधान रहें। – LittleBobbyTables

44

क्या वास्तव में अजीब बात है कि मूल्य आप इंटरफ़ेस में वैकल्पिक पैरामीटर के लिए डाल वास्तव में एक फर्क नहीं पड़ता है। मुझे लगता है कि आपको सवाल करना है कि क्या मूल्य एक इंटरफ़ेस विवरण या कार्यान्वयन विवरण है। मैंने बाद वाले लोगों को कहा होगा लेकिन चीजें पूर्व की तरह व्यवहार करती हैं। उदाहरण के लिए निम्नलिखित कोड 1 0 2 5 3 7 आउटपुट करता है।

// Optput: 
// 2 5 
namespace ScrapCSConsole 
{ 
    using System; 

    interface IMyTest 
    { 
     void MyTestMethod(int notOptional, int optional = 5); 
    } 

    class MyTest : IMyTest 
    { 
     public void MyTestMethod(int notOptional, int optional) 
     { 
      Console.WriteLine(string.Format("{0} {1}", notOptional, optional)); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      MyTest myTest1 = new MyTest(); 
      // The following line won't compile as it does not pass a required 
      // parameter. 
      //myTest1.MyTestMethod(1); 

      IMyTest myTest2 = myTest1; 
      myTest2.MyTestMethod(2); 
     } 
    } 
} 

क्या एक गलती हो रहा है लेकिन यह है कि अगर:

// Output: 
// 1 0 
// 2 5 
// 3 7 
namespace ScrapCSConsole 
{ 
    using System; 

    interface IMyTest 
    { 
     void MyTestMethod(int notOptional, int optional = 5); 
    } 

    interface IMyOtherTest 
    { 
     void MyTestMethod(int notOptional, int optional = 7); 
    } 

    class MyTest : IMyTest, IMyOtherTest 
    { 
     public void MyTestMethod(int notOptional, int optional = 0) 
     { 
      Console.WriteLine(string.Format("{0} {1}", notOptional, optional)); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      MyTest myTest1 = new MyTest(); 
      myTest1.MyTestMethod(1); 

      IMyTest myTest2 = myTest1; 
      myTest2.MyTestMethod(2); 

      IMyOtherTest myTest3 = myTest1; 
      myTest3.MyTestMethod(3); 
     } 
    } 
} 

दिलचस्प बात की तरह है कि यह भी ऐसा ही करने की जरूरत नहीं है अगर आपके इंटरफेस को लागू करने के लिए एक पैरामीटर वैकल्पिक वर्ग बनाता है आप इंटरफ़ेस को लागू करते हैं स्पष्ट रूप से वैकल्पिक मूल्य के लिए कक्षा में जो मान आप देते हैं वह व्यर्थ है। निम्नलिखित उदाहरण में आप मूल्य 9 का उपयोग कैसे कर सकते हैं? संकलन करते समय यह चेतावनी भी नहीं देता है।

// Optput: 
// 2 5 
namespace ScrapCSConsole 
{ 
    using System; 

    interface IMyTest 
    { 
     void MyTestMethod(int notOptional, int optional = 5); 
    } 

    class MyTest : IMyTest 
    { 
     void IMyTest.MyTestMethod(int notOptional, int optional = 9) 
     { 
      Console.WriteLine(string.Format("{0} {1}", notOptional, optional)); 
     } 
    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      MyTest myTest1 = new MyTest(); 
      // The following line won't compile as MyTest method is not available 
      // without first casting to IMyTest 
      //myTest1.MyTestMethod(1); 

      IMyTest myTest2 = new MyTest();    
      myTest2.MyTestMethod(2); 
     } 
    } 
} 
2

आपको कार्यान्वयन में पैरामीटर वैकल्पिक बनाने की आवश्यकता नहीं है। आपका कोड तो कुछ और अधिक समझ कर देगा:

public interface IFoo 
{ 
     void Bar(int i, int j = 0); 
} 

public class Foo 
{ 
     void Bar(int i, int j) { // do stuff } 
} 

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

+2

कार्यान्वयन में डिफ़ॉल्ट मान का प्रभाव होगा यदि आपका संदर्भ इंटरफ़ेस के बजाय कक्षा के साथ टाइप किया गया है। –

2

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

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