2010-09-29 19 views
9

मैंने उन चीज़ों के कुछ उदाहरण देखे हैं जो काम करते हैं और सी # में लैम्ब्डा कार्यों और अज्ञात प्रतिनिधियों से निपटने के दौरान काम नहीं करते हैं। यहाँ क्या चल रहा है?प्रतिनिधि/लैम्ब्डा टाइपिंग और जबरदस्ती कैसे काम करते हैं?

class Test : Control { 
    void testInvoke() { 
     // The best overloaded method match for 'Invoke' has some invalid arguments 
     Invoke(doSomething); 

     // Cannot convert anonymous method to type 'System.Delegate' because it is not a delegate type 
     Invoke(delegate { doSomething(); }); 

     // OK 
     Invoke((Action)doSomething); 

     // OK 
     Invoke((Action)delegate { doSomething(); }); 

     // Cannot convert lambda expression to type 'System.Delegate' because it is not a delegate type 
     Invoke(() => doSomething()); 

     // OK 
     Invoke((Action)(() => doSomething())); 
    } 

    void testQueueUserWorkItem() { 
     // The best overloaded method match for 'QueueUserWorkItem' has some invalid arguments 
     ThreadPool.QueueUserWorkItem(doSomething); 

     // OK 
     ThreadPool.QueueUserWorkItem(delegate { doSomething(); }); 

     // The best overloaded method match for 'QueueUserWorkItem' has some invalid arguments 
     ThreadPool.QueueUserWorkItem((Action)doSomething); 

     // No overload for 'doSomething' matches delegate 'WaitCallback' 
     ThreadPool.QueueUserWorkItem((WaitCallback)doSomething); 

     // OK 
     ThreadPool.QueueUserWorkItem((WaitCallback)delegate { doSomething(); }); 

     // Delegate 'WaitCallback' does not take '0' arguments 
     ThreadPool.QueueUserWorkItem(() => doSomething()); 

     // OK 
     ThreadPool.QueueUserWorkItem(state => doSomething()); 
    } 

    void doSomething() { 
     // ... 
    } 
} 

वैसे यह बहुत सारे उदाहरण हैं। मुझे लगता है कि मेरे सवालों का इस प्रकार हैं:

  1. क्यों Invoke हमेशा एक लैम्ब्डा समारोह या एक अनाम प्रतिनिधि मना करता है, अभी तक ThreadPool.QueueUserWorkItem ठीक करता है?

  2. क्या बिल्ली "अज्ञात विधि को 'सिस्टम' डिलीगेट 'टाइप करने के लिए परिवर्तित नहीं कर सकता क्योंकि यह एक प्रतिनिधि प्रकार नहीं है" वैसे भी?

  3. ThreadPool.QueueUserWorkItem कोई पैरामीटर के साथ एक अज्ञात प्रतिनिधि को स्वीकार क्यों करता है, लेकिन कोई पैरामीटर के साथ लैम्ब्डा अभिव्यक्ति नहीं है?

उत्तर

9
  1. ThreadPool.QueueUserWorkItem उसके हस्ताक्षर में एक विशिष्ट प्रतिनिधि है; आमंत्रित करें Delegate है। लैम्ब्डा अभिव्यक्तियों और अज्ञात विधियों को केवल एक विशिष्ट प्रतिनिधि प्रकार में परिवर्तित किया जा सकता है।

  2. यह एक बुरा त्रुटि संदेश है। इसका मतलब है, "मुझे नहीं पता कि आप किस प्रतिनिधि प्रकार को बदलने की कोशिश कर रहे हैं।"

  3. आप सभी पर एक पैरामीटर सूची के बिना एक अज्ञात विधि का उपयोग कर रहे हैं जिसे किसी भी प्रतिनिधि प्रकार में परिवर्तित किया जा सकता है जो आउट/रेफ पैरामीटर का उपयोग नहीं करता है। यदि आपने delegate() { ... } (यानी स्पष्ट रूप से खाली पैरामीटर सूची) की कोशिश की तो यह काम नहीं करेगा। यह "मुझे पैरामीटर की परवाह नहीं है" अज्ञात विधियों की क्षमता केवल सुविधा है जिसमें वे लैम्ब्डा अभिव्यक्ति नहीं करते हैं।

यह सरल कार्य के संदर्भ में यह सब प्रदर्शित करने के लिए सबसे आसान है IMO:

// Doesn't work: no specific type 
Delegate d =() => Console.WriteLine("Bang"); 

// Fine: we know the exact type to convert to 
Action a =() => Console.WriteLine("Yay"); 

// Doesn't work: EventHandler isn't parameterless; we've specified 0 parameters 
EventHandler e1 =() => Console.WriteLine("Bang"); 
EventHandler e2 = delegate() { Console.WriteLine("Bang again"); }; 

// Works: we don't care about parameter lists 
EventHandler e = delegate { Console.WriteLine("Lambdas can't do this"); }; 
+4

और मैंने सोचा कि मैं प्रतिनिधियों और lambdas समझा। मैं बहुत मूर्ख था। – recursive

+0

हमेशा के लिए अच्छी चीजें, +1 के लिए +1 ... ... एकमात्र विशेषता है जो लैम्ब्डा अभिव्यक्ति नहीं करती है। " – Ani

+1

@recursive, यदि आप और जानना चाहते हैं, अभिव्यक्ति पेड़ों पर पढ़ें। लैम्ब्डा अभिव्यक्तियों के बारे में दिलचस्प बात यह है कि वे वास्तव में _expressions_ हैं, जो व्यक्त किए जा रहे हैं के लिए एक समृद्ध वर्णनात्मक मॉडल के साथ, और प्रतिनिधि प्रतिनिधि पैरामीटर को तर्क पारित करने के लिए केवल एक वाक्य रचनात्मक शॉर्टकट नहीं है। यह वही है जो LINQ से SQL को होने की अनुमति देता है। http://msdn.microsoft.com/en-us/library/bb397951.aspx –

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