2011-10-07 9 views
29

मैं निम्नलिखित कोड है:पैरामीटर कार्रवाई <T1, T2, T3> T3 वैकल्पिक हो सकता है

वैकल्पिक param3 पैरामीटर का
public static MyMethod() 
{ 
    ...Do something 
    ProtectedMethod(param1, param2); 
    ...Do something 
} 

protected static void ProtectedMethod(IEnumerable<string> param1, string param2, int param3 = 1) 
{ 
    ... Do something 
} 

लें नोटिस।

अब कुछ कारणों से मुझे MyMethod विधि के कोड को अपनी कक्षा में निकालने की आवश्यकता है, लेकिन मैं इसके साथ विरासत में आने वाले सभी वर्गों के कारण संरक्षित विधि को निकाला नहीं जा सकता और मुझे परिवर्तनों को रखने की आवश्यकता है छोटा और अलग तो मैंने सोचा कि मेरे पास एक एक्शन <> संरक्षित विधि के समान हस्ताक्षर के साथ नई कक्षा में प्रतिनिधि हो सकता है।

protected readonly Action<IEnumerable<string>, string, int> m_ProtectedMethod; 

निकाले कोड यह पसंद नहीं करता क्योंकि यह कहते विधि केवल दो मापदंडों के साथ लागू किया जा रहा है:

समस्या यह है कि अगर मैं इस तरह प्रतिनिधि घोषित है।

और अगर मैं तो जैसे प्रतिनिधि घोषित:

protected readonly Action<IEnumerable<string>, string> m_ProtectedMethod; 

जब मैं नया वर्ग के लिए एक पैरामीटर के रूप में भेजें यह यह पसंद नहीं करता क्योंकि या तो विधि तीन पैरामीटर नहीं दो होने के रूप में परिभाषित किया गया है।

अभी तक इसे हल करने का एकमात्र तरीका वैकल्पिक पैरामीटर को खत्म करने के लिए ProtectedMethod का अधिभारित संस्करण बनाना है।

क्या यह एकमात्र विकल्प है या ऐसा करने का दूसरा तरीका है क्योंकि अब पसंदीदा विकल्प ओवरलोडेड विधियों के बजाय वैकल्पिक पैरामीटर होना है?

+0

सभी संबंधित नहीं हैं, लेकिन कुछ ऐसा दिखता है: http://stackoverflow.com/questions/707780/is-there-a-reasonable-approach-to-default-type-parameters-in-c-sharp- जेनेरिक – nawfal

उत्तर

29

वैकल्पिक पैरामीटर एक विधि या प्रतिनिधि पैरामीटर की विशेषता है। जब आप हस्ताक्षर (विधि या प्रतिनिधि) को कॉल करते हैं जिसमें संकलन-समय पर एक ज्ञात वैकल्पिक पैरामीटर होता है, तो संकलक कॉलसाइट पर वैकल्पिक पैरामीटर मान डालेगा।

रनटाइम वैकल्पिक पैरामीटर से अवगत नहीं है, इसलिए आप एक प्रतिनिधि नहीं बना सकते हैं जो इसे कॉल करने पर वैकल्पिक पैरामीटर डालता है।

public delegate void MyDelegate(IEnumerable<string> param1, string param2, int param3 = 1); 

जब इस प्रतिनिधि बुला, आप विधि की घोषणा की तीसरी पैरामीटर छोड़, परवाह किए बिना सक्षम हो जाएगा (रों:

इसके बजाय, आप एक वैकल्पिक पैरामीटर के साथ एक कस्टम प्रतिनिधि प्रकार की घोषणा करने की जरूरत है) इसमें शामिल है।

+2

तर्क टाइप कर सकते हैं वैकल्पिक? –

+0

@ जोएल: आपका क्या मतलब है? – SLaks

+2

@ जोएल कोहोउर्न - नहीं - जेनेरिक नए प्रकार –

1

यह इस बात पर निर्भर करेगा कि कैसे m_ProtectedMethod उपभोग किया जाएगा, लेकिन मुझे अपनी स्थिति में एक समझौता हुआ, जहां मैं दूसरे से अधिक अधिभार का उपयोग करता हूं।

सीधे शब्दों में एक सरल (होने कम सामान्य पैरामीटर) कार्रवाई <> चर, जो और अधिक जटिल आपूर्ति की कार्रवाई चर विधि कॉल परिभाषित करते हैं। यह या तो (i) उपयोग पर स्थानीय दायरे में पूरा किया जा सकता है; या (ii) कार्य संपत्ति या वस्तु निर्माण के असाइनमेंट पर ऑब्जेक्ट स्कोप।

क्योंकि परिवर्तनीय/संपत्ति अधिभार जैसी कोई चीज़ नहीं है, जिसके परिणामस्वरूप दो संबंधित कार्य चर के लिए आपको दो अलग-अलग नामों की आवश्यकता है।

ईजी मैं: स्थानीय स्कोप (शायद सबसे अपने परिदृश्य के लिए उपयुक्त नहीं)

public MyMethod(Action<IEnumerable<string>, string, int> m_ProtectedMethod2) 
{ 
    Action<IEnumerable<string>, string> m_ProtectedMethod = (p1,p2) => { 
     m_ProtectedMethod2(p1,p2,1); //The value 1 is the default 3rd parameter 
    } 

    ...Do something 
    m_ProtectedMethod(param1, param2); 
    ...Do something 
    ...If something 
     m_ProtectedMethod2(param1, param2, param3); //Calling the more complex form directly 
    ...Do something 
} 

ईजी ii: ऑब्जेक्ट स्कोप

private Action<IEnumerable<string>, string, int> m_ProtectedMethod2 = null; 
private Action<IEnumerable<string>, string> m_ProtectedMethod = null; 
protected Action<IEnumerable<string>, string, int> ProtectedMethod 
{ 
    get { return m_ProtectedMethod2; } 
    set { 
     m_ProtectedMethod2 = value; 
     m_ProtectedMethod = (p1,p2) => { 
     m_ProtectedMethod2(p1,p2,1); //The value 1 is the default 3rd parameter 
     } 
    } 
} 

public MyMethod() 
{ 
    ...Do something 
    m_ProtectedMethod(param1, param2); 
    ...Do something 
    ...If something 
     m_ProtectedMethod2(param1, param2, param3); //Calling the more complex form directly 
    ...Do something 
} 

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

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