2013-11-01 7 views
8

मैं निम्नलिखित कोड है:तरीके मूल्य और संदर्भ पैरामीटर प्रकार के साथ अधिक भार

class Calculator 
    { 
     public int Sum(int x, int y) 
     { 
      return x + y; 
     } 



     public int Sum(out int x, out int y) 
     { 
      x = y = 10; 
      return x + y; 
     } 


    } 

    class Program 
    { 
     static void Main(string[] args) 
     { 
      int x = 10, y = 20; 
      Calculator calculator = new Calculator(); 

      Console.WriteLine (calculator.Sum (x , y)); 
      Console.WriteLine (calculator.Sum (out x , out y)); 

     } 
    } 

इस कोड के बावजूद कि तरीकों हस्ताक्षर केवल differenciated out कीवर्ड हो रहे हैं अच्छी तरह से काम करते हैं।

लेकिन निम्नलिखित कोड काम नहीं किया:

class Calculator 
    { 

     public int Sum(ref int x, ref int y) 
     { 
      return x + y; 
     } 

     public int Sum(out int x, out int y) 
     { 
      x = y = 10; 
      return x + y; 
     } 

    } 


    class Program 
    { 
     static void Main(string[] args) 
     { 
      int x = 10, y = 20; 
      Calculator calculator = new Calculator(); 

      Console.WriteLine (calculator.Sum (ref x , ref y)); 
      Console.WriteLine (calculator.Sum (out x , out y)); 

     } 
    } 

क्यों इस कोड काम नहीं किया? क्या विधियों के हस्ताक्षर के भाग और बाहर के कीवर्ड हैं?

+0

'ref' और' out' लगभग एक ही चीज़ के लिए संकलित, इसलिए सी # आपको ऐसा करने की अनुमति नहीं देता है। –

उत्तर

10

out parameter modifier (C# Reference)

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

यह भी देखें: ref (C# Reference) एक वर्ग की

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

+1

यदि उन्हें विधि हस्ताक्षर का हिस्सा नहीं माना जाता है, तो पहला उदाहरण क्यों काम करता है? –

+2

@ डेविड्स .: मूल रूप से वह दस्तावेज टूट गया है। वे * हस्ताक्षर का हिस्सा माना जाता है, क्योंकि मेरे spec उद्धरण इंगित करता है। यह सिर्फ ओवरलोडिंग उद्देश्यों के लिए उन्हें हस्ताक्षर में बराबर माना जाता है। –

+0

वह संपादन वास्तव में डेविड के प्रश्न को संतोषजनक रूप से उत्तर नहीं देता है, आईएमओ। सी # spec स्पष्ट है कि "दयालु" पैरामीटर (मूल्य, संदर्भ, आउटपुट) * हस्ताक्षर का हिस्सा है, लेकिन अधिभार के लिए एक प्रतिबंध के साथ। –

1

इस विनिर्देशन कर रहा है। MSDN पेज out parameter modifier (C# Reference)

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

6

अन्य उत्तर देने के लिए कुछ अलग ढंग से उद्धृत करने के लिए, इस सी # 5 विनिर्देश, जो मैं नहीं बल्कि स्पष्ट और "संदर्भ तुलना में अधिक सटीक लगता है की धारा 3.6 से है गाइड ":

out हालांकि और ref पैरामीटर संशोधक एक हस्ताक्षर का हिस्सा माना जाता है, सदस्यों एक ही प्रकार में घोषित हस्ताक्षर में अलग नहीं कर सकते हैं केवल रेफरी द्वारा और बाहर। एक संकलन-समय त्रुटि तब होती है जब दो सदस्यों को एक ही प्रकार में हस्ताक्षर के साथ घोषित किया जाता है जो out संशोधक दोनों विधियों के सभी पैरामीटर ref संशोधक में बदल दिए गए थे। हस्ताक्षर मिलान के अन्य उद्देश्यों के लिए (उदा।, छुपाएं या ओवरराइडिंग), ref और out हस्ताक्षर का हिस्सा माना जाता है और एक-दूसरे से मेल नहीं खाते हैं। (यह प्रतिबंध सामान्य भाषा इंफ्रास्ट्रक्चर (सीएलआई) पर चलाने के लिए सी # प्रोग्रामों का आसानी से अनुवाद करने की अनुमति देना है, जो पूरी तरह से ref और out में भिन्न विधियों को परिभाषित करने का एक तरीका प्रदान नहीं करता है।)

ध्यान दें कि dynamic की एक पैरामीटर प्रकार थोड़ा यहाँ समान है - जहाँ तक CLR का संबंध है, कि बस प्रकार object की एक पैरामीटर है, तो यह अमान्य है:

void InvalidOverload(object x) {} 
void InvalidOverload(dynamic x) {} 

उस मामले में हालांकि, पैरामीटर प्रकार dynamic के पैरामीटर प्रकार के साथ पैरामीटर प्रकार के साथ एक विधि के लिए यह ठीक है, object के पैरामीटर प्रकार के साथ ओवरराइड करने के लिए या इसके विपरीत - महत्वपूर्ण बिंदु यह है कि वे कॉलर्स के बराबर हैं, जबकि यह out के सत्य नहीं है/ref

-1

यह मूल रूप से एक संकलन त्रुटि है क्योंकि दोनों रेफरी आउट लगभग समान हैं। दोनों लगभग समान हैं लेकिन पैरामीटर को पास करने वाले मान को प्रारंभ करने की आवश्यकता नहीं है।

+1

नहीं, वे "मान प्रकार को संदर्भ प्रकार के रूप में भेजने के लिए उपयोग नहीं किए जाते हैं" - यह एक भयानक स्पष्टीकरण है कि यह कैसे काम करता है, और इस तथ्य को अनदेखा करता है कि आप संदर्भ प्रकार पैरामीटर के साथ 'ref' और' out' का उपयोग भी कर सकते हैं। और यदि कारण सी # के साथ अलग-अलग व्यवहार करना है लेकिन सीएलआर ऐसा नहीं कर रहा है ... यदि अंतर सीएलआर द्वारा समर्थित था, तो ओवरलोडिंग ठीक रहेगी। –

+0

@ जोन स्कीट: धन्यवाद जॉन, मैं इसे सही कर दूंगा, आपकी बहुमूल्य टिप्पणी के लिए धन्यवाद। –

+0

अब यह वास्तव में मूल प्रश्न का सही उत्तर नहीं देता है। आप यह कह रहे हैं क्योंकि वे लगभग समान हैं - लेकिन यह आसानी से मामला हो सकता है और अधिभार अभी भी वैध हो सकता है। –

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