2010-02-18 26 views
14

के साथ एक अज्ञात विधि को प्रतिनिधि करने के लिए असाइन नहीं किया जा सकता है, मैं कम विशिष्ट पैरामीटर प्रकार के साथ ऑब्जेक्ट d ऑब्जेक्ट करने के लिए M विधि निर्दिष्ट करने में सक्षम हूं, लेकिन जब मैं एक हस्ताक्षर के साथ एक अनाम विधि असाइन करना चाहता हूं विधि M से d के रूप में, मुझे एक त्रुटि मिलती है।कम विशिष्ट पैरामीटर प्रकार

वह क्यों है?

class derivedEventArgs : EventArgs { } 

delegate void newDelegate(object o, derivedEventArgs e); 

static void Main(string[] args) 
{ 
    newDelegate d = M; // ok 
       d = (object o, EventArgs e) => { }; // error 
} 

public static void M(object o, EventArgs e) { } 
+2

आपके पास निश्चित रूप से कुछ दिलचस्प नामकरण सम्मेलन चल रहे हैं ... –

उत्तर

15

जेरेड निश्चित रूप से सही है कि यह डिज़ाइन द्वारा किया गया है।

उस डिज़ाइन का कारण यह है कि contravariant विधि रूपांतरण मामले में, आपके पास एक विधि हो सकती है जिसे आपने नहीं लिखा था, और इसे एक प्रतिनिधि चर को असाइन किया जा रहा है जिसे आपने लिखा नहीं था। आप प्रकारों को नियंत्रित नहीं करते हैं। तो हम आप पर थोड़ा आसान हो जाते हैं और पैरामीटर को विरोधाभासी रूप से मिलान करते हैं और रिटर्न प्रकारों को कॉन्वर्सेटली से मेल खाते हैं।

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

+0

महान जवाब। आप दोनों की मदद करने के लिए धन्यवाद – AspOnMyNet

16

यह सी # भाषा विनिर्देश की धारा 6.5 में शामिल है। यदि आप स्पष्ट रूप से किसी अज्ञात फ़ंक्शन के पैरामीटर टाइप करते हैं, तो उन्हें संगत हस्ताक्षर होने के लिए दोनों प्रकार और संशोधक में मेल खाना चाहिए।

विशेष रूप से, एक प्रतिनिधि प्रकार डी एक गुमनाम समारोह एफ प्रदान की

के साथ संगत है ...

एफ एक स्पष्ट टाइप किया पैरामीटर सूची है, तो डी में प्रत्येक पैरामीटर एक ही प्रकार के और संशोधक है एफ

+1

+1 बहुत तेज़ उत्तर। –

2

जबकि आपको अपना जवाब मिल गया है, तो यह एक वर्कअराउंड प्रदान करेगा यदि यह आवश्यक है। कहते हैं, तुम सब मिल गया जो मामले में आप इसे अपने newDelegate प्रकार के कनवर्ट करना चाहते हैं हस्ताक्षर (object, EventArgs) के एक प्रतिनिधि है, तो आप कर सकता है:

SomeDelegate p = (object o, EventArgs e) => { }; //comes from somewhere 
NewDelegate d = (o, e) => p(o, e); //can rewrite like this 
वैकल्पिक रूप से जेनरिक साथ

और (विपरीत) सामान्य प्रतिनिधियों की विचरण सुविधा, आप कर सकते हैं इसे एक प्रतिनिधि प्रकार के साथ करें:

delegate void NewDelegate<in T>(object o, T e) where T : EventArgs; 

//then 
NewDelegate<EventArgs> p = (object o, EventArgs e) => { }; //comes from somewhere 
NewDelegate<DerivedEventArgs> d = p; //straightforward assignable - contravariance 
संबंधित मुद्दे