2012-10-13 26 views
13

इस कोड टुकड़ा में:लैम्बडास क्रियाओं को क्रियाओं में परिवर्तित क्यों कर सकता है?

List<String> names = new List<String>(); 
names.Add("Bruce"); 
names.Add("Tom"); 
names.Add("Tim"); 
names.Add("Richard"); 

names.ForEach(x => Print(x)); 

private static string Print(string s) 
{ 
    Console.WriteLine(s); 
    return s; 
} 

Print यकीन है कि के लिए एक Action के बाद से यह string लौटा रहा है नहीं है, हालांकि x=> Print(x) है, क्यों?

+3

कृपया इस प्रश्न का शीर्षक सुधारें। Google इसका उपयोग अपने खोज परिणामों को शीर्षक देने के लिए करता है, और आपका शीर्षक गुगल करने योग्य नहीं है। –

उत्तर

16

लैम्ब्डा अभिव्यक्ति x => Print(x) का प्रकार इसके संदर्भ के आधार पर निर्धारित किया गया है। चूंकि संकलक जानता है कि लैम्ब्डा को Action<string> पर असाइन किया गया है, तो संकलक Print(s) विधि के रिटर्न प्रकार को अनदेखा करता है जैसे कि यह कथन अभिव्यक्ति था।

यह एक वैध रूपांतरण है:

Action<string> myAction = y => Print(y); 

दूसरे शब्दों में, दोनों

Print("something"); 

और

int x = Print("something"); 

Print विधि का सही प्रयोग कर रहे हैं; वे लैम्ब्स में उसी तरह इस्तेमाल किया जा सकता है।

+0

प्रिंट प्रिंटिंग स्ट्रिंग के बाद, क्यों कंपाइलर रिटर्न प्रकार को शून्य और मैच एक्शन के रूप में ले सकता है? –

+4

क्योंकि स्ट्रिंग के साथ करने के लिए एक कानूनी बात इसे फेंक देती है। आपको विशेष रूप से यह बताने की आवश्यकता नहीं है कि आप एक वापसी मूल्य फेंक रहे हैं - इसका उपयोग न करें पर्याप्त है। –

+0

वास्तव में, लगभग हर बार जब आप एक चर निर्दिष्ट कर रहे होते हैं, तो आप वही काम कर रहे हैं, क्योंकि असाइनमेंट अभिव्यक्ति असाइन किए गए मान को वापस कर देती है! तो एक क्रिया जो एक राइबल निर्दिष्ट करती है वही काम कर रही है। –

9

x => Print(x) एक लैम्ब्डा कि करने के लिए यहाँ एक विधि में बदल गया है बराबर है:

string MyPrintLambda(string x) { return Print(x); } 

:

void MyPrintLambda(string x) { Print(x); } 

हैं संदर्भ के लिए कहते हैं, कहा जाता था, एक Func<string, string>, यह इस गया होता या यदि यह Func<string, object> था, तो यह यह होगा:

object MyPrintLambda(string x) { return Print(x); } 

क्योंकि संकलक x => Print(x) को Action<string> में आसानी से वापसी प्रकार को अनदेखा करके बदल सकता है (यानी। पहला उदाहरण), यह संकलित कर सकते हैं।

+1

आखिरी बिट बिल्कुल सही नहीं है, 'नाम। फॉरएच (प्रिंट)' संकलित नहीं होगा, क्योंकि 'प्रिंट' एक 'एक्शन ', 'x => प्रिंट (x) 'में परिवर्तनीय नहीं है, हालांकि, चूंकि अभिव्यक्ति के प्रकारों को – mlorbetske

+0

@mlorbetske के आधार पर परिभाषित किया गया है, तो आप अभी उस बिट को हटा चुके हैं। –

4

एक ही कारण है कि यह वैध होगा के लिए:

foreach (string name in names) 
{ 
    Print(name); 
} 

प्रिंट() विधि के रूप में अच्छी तरह से है कि कोड में एक मान देता है, लेकिन कोई भी यह एक त्रुटि होने की अपेक्षा करेंगे। इसे केवल वापसी मूल्य को फेंकने की अनुमति है।

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