2010-08-10 12 views
6
class Program 
{ 
    public delegate void VoidMethodDelegate(); 
    public delegate int IntMethodDelegate(); 

    static void Main(string[] args) 
    { 
     Test(IntMethod); 
     Test(VoidMethod); 
    } 

    static int IntMethod() 
    { 
     return 1; 
    } 

    static void VoidMethod() 
    { 
    } 

    static void Test(VoidMethodDelegate method) 
    { 
    } 

    static void Test(IntMethodDelegate method) 
    { 
    } 
} 

मैं एक अधिभारित विधि स्थापित करने की कोशिश कर रहा हूं जो दो अलग-अलग प्रकार के प्रतिनिधियों को ले जाएगा। प्रतिनिधि केवल रिटर्न प्रकार से भिन्न होते हैं - दोनों मामलों में वे कोई इनपुट पैरामीटर नहीं लेते हैं। तो उपर्युक्त उदाहरण में, मैं टेस्ट() को कॉल करने में सक्षम होना चाहता हूं और इसे या तो एक विधि पास कर सकता हूं जो शून्य लौटाता है, या एक तरीका जो int लौटाता है। जब मैं कोड ऊपर संकलन, मैं इन त्रुटियों को मिलता है:ओवरलोडेड विधि के साथ संदिग्ध कॉल त्रुटि जो अलग-अलग रिटर्न प्रकारों के साथ 2 प्रतिनिधि लेती है

त्रुटि CS0121: 'ConsoleApplication1.Program.Test (ConsoleApplication1.Program.VoidMethodDelegate)' : कॉल निम्न विधियों या गुणों के बीच अस्पष्ट है और 'ConsoleApplication1.Program.Test (ConsoleApplication1.Program.IntMethodDelegate)'

त्रुटि CS0407: 'int ConsoleApplication1.Program.IntMethod()' गलत वापसी प्रकार है

त्रुटि CS0121: कॉल अस्पष्ट है निम्न विधियों या गुणों के बीच : 'ConsoleApplication1.Program.Test (ConsoleApplication1.Program.VoidMethodDelegate)' और 'ConsoleApplication1.Program.Test (ConsoleApplication1.Program.IntMethodDelegate)'

मैं जानता हूँ कि मैं त्रुटियों के आसपास काम कर सकते हैं अगर मैं नई साथ प्रतिनिधियों बनाने के बजाय सिर्फ सीधे विधि से गुजर रहा, इस तरह:

static void Main(string[] args) 
    { 
     Test(new IntMethodDelegate(IntMethod)); 
     Test(new VoidMethodDelegate(VoidMethod)); 
    } 

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

क्या कोई मुझे बता सकता है कि संकलक शिकायत कर रहा है कि यह संदिग्ध क्यों है? मुझे समझ में नहीं आता कि क्यों कंपाइलर तय नहीं कर सकता कि दो ओवरलोड का उपयोग करने के लिए कौन सा है।

+0

संभावित डुप्लिकेट [कंपाइलर अस्पष्ट आमंत्रण त्रुटि - अज्ञात विधि और Func <> या एक्शन] के साथ विधि समूह (http://stackoverflow.com/questions/2057146/compiler-ambiguous-invocation-error-anonymous-method-and -method-group-with-fun) – nawfal

+0

यह नहीं पता कि यह कितना सुंदर है, लेकिन 'टेस्ट (नया IntMethodDelegate (IntMethod)) के बजाय;' आप 'टेस्ट ((IntMethodDelegate) IntMethod) का उपयोग कर सकते हैं; '। एक विधि समूह से एक प्रतिनिधि प्रकार में रूपांतरण आमतौर पर निहित है, लेकिन आप (स्पष्ट) कास्ट वाक्यविन्यास (और इस मामले में होना) का भी उपयोग कर सकते हैं। –

उत्तर

7

असल में यह एक अधिभार है कि ओवरलोडिंग कैसे की जाती है, और विधि समूह रूपांतरण कैसे हल किए जाते हैं। यदि आप चाहें तो सटीक कारणों को ढूंढने के लिए मैं spec के माध्यम से wade करने का प्रयास कर सकता हूं, लेकिन बुरी खबर यह है कि यह वही तरीका है। यह संभव इस मामले में एक कंपाइलर बग है, लेकिन यह संभावना है कि यह कल्पना का एक मुश्किल सा है।

I लगता है कि this SO question may be relevant, लेकिन मैंने अभी तक जांच नहीं की है।

new का उपयोग करके इसे हल करने के बजाय, मैं सुझाव दूंगा कि विभिन्न विधि नामों का उपयोग करने का विकल्प लें। अधिभार में सभी प्रकार के स्नीकी कोने के मामले होते हैं - यह कम से कम अपेक्षाकृत हानिकारक है कि यह ओवरलोड को चुनने के बजाय संकलन-समय त्रुटि उत्पन्न कर रहा है जिसे आप निष्पादन समय पर नहीं चाहते हैं। ओवरलोडिंग को हटाने अक्सर एक अच्छी बात है :)

संपादित करें: मुझे पूरा यकीन है कि अन्य SO प्रश्न प्रासंगिक है, वास्तव में। मेरा सुझाव है कि आप खुद को एक कप कॉफी प्राप्त करें, सी # 4 स्पेक, और फिर एरिक के जवाब को बहुत सावधानी से पढ़ें। फिर विधि नाम बदलें ताकि आपको इसके बारे में और सोचने की आवश्यकता न हो।

+0

लिंक के लिए धन्यवाद, मुझे अपनी शुरुआती खोजों में से एक याद आया। मैं अलग-अलग नामित विधियों का उपयोग करने के साथ सहमत हूं, यही वह है जो मैं करूँगा, मैं बस यह सुनिश्चित करना चाहता था कि मुझे कुछ स्पष्ट याद नहीं आया। –

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