5

मैंने अभी अधिभार संकल्प के साथ एक अजीब व्यवहार देखा है।ओवरलोडिंग, जेनेरिक टाइप अनुमान और 'पैराम्स' कीवर्ड

मान लें मैं निम्न विधि है:

public static void DoSomething<T>(params T[] items) 
{ 
    // Whatever 

    // For debugging 
    Console.WriteLine("DoSomething<T>(params T[] items)"); 
} 
:

public static void DoSomething<T>(IEnumerable<T> items) 
{ 
    // Whatever 

    // For debugging 
    Console.WriteLine("DoSomething<T>(IEnumerable<T> items)"); 
} 

अब, मुझे पता है, कि इस विधि अक्सर स्पष्ट तर्क की एक छोटी संख्या के साथ बुलाया जाएगा तो सुविधा के लिए मैं इस अधिभार जोड़ने

अब मैं इन तरीकों कॉल करने के लिए प्रयास करें:

var items = new List<string> { "foo", "bar" }; 
DoSomething(items); 
DoSomething("foo", "bar"); 

लेकिन दोनों ही मामलों में, params के साथ अधिभार कहा जाता है। List<T> के मामले में मुझे IEnumerable<T> ओवरलोड होने की उम्मीद होगी, क्योंकि यह एक बेहतर मैच (कम से कम मेरे लिए) लगता है।

क्या यह व्यवहार सामान्य है? क्या कोई इसे समझा सकता है? मुझे एमएसडीएन दस्तावेज़ों में इसके बारे में कोई स्पष्ट जानकारी नहीं मिली ... यहां अधिभार संकल्प नियम क्या शामिल हैं?

उत्तर

9

सी # 3.0 विनिर्देश की धारा 7.4.3 यहां प्रासंगिक बिट है। मूल रूप से पैरामीटर सरणी का विस्तार किया है, तो आप तुलना कर रहे हैं:

public static void DoSomething<T>(T item) 

और

public static void DoSomething<T>(IEnumerable<T> item) 

T पहले मैच के लिए List<string> होने के लिए मान लिया जाता है और दूसरे मैच के लिए T होने के लिए मान लिया जाता है string

अब पैरामीटर प्रकार के लिए तर्क के लिए शामिल रूपांतरणों पर विचार करें - पहले में यह List<string> से List<string> है; दूसरे में यह List<string> से IEnumerable<string> है। पहला रूपांतरण 7.4.3.4 में नियमों के अनुसार दूसरे से बेहतर है।

प्रतिबिंबित बिट प्रकार अनुमान है। यदि आप समीकरण से बाहर है कि ले, यह के रूप में आप यह करने के लिए उम्मीद से काम करेगा:

var items = new List<string> { "foo", "bar" }; 
DoSomething<string>(items); 
DoSomething<string>("foo", "bar"); 

उस बिंदु पर, वहाँ केवल एक ही प्रत्येक कॉल में लागू समारोह सदस्य है।

+0

धन्यवाद जॉन, यह बिल्कुल मुझे स्पष्टीकरण की आवश्यकता है। क्या मैं इसे काम करने के लिए कुछ प्रकार का कामकाज कर रहा हूं? यदि मुझे नहीं लगता कि मुझे एक अलग नाम का उपयोग करना होगा ... –

+0

हां, मैंने देखा है कि यह काम करता है अगर मैं सामान्य प्रकार पैरामीटर को स्पष्ट रूप से निर्दिष्ट करता हूं। लेकिन मैं टाइप अनुमान का लाभ खो देता हूं ... –

+4

मैं स्पष्टता के लिए एक अलग नाम का उपयोग करने का सुझाव दूंगा - या यदि आप केवल एक से अधिक आइटम के साथ इसका उपयोग करने जा रहे हैं, तो आप '(टी पहले, पैराम्स टी [] अन्य) ' –

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