2010-04-22 15 views
24

मुझे उम्मीद है कि मैंने अपने प्रश्न का शीर्षक उचित रूप से लिखा है।सी # इनलाइन अज्ञात लैम्बडा या प्रतिनिधियों का उपयोग क्यों नहीं कर सकता?

ग # मैं (प्रतिनिधियों के रूप में) lambdas उपयोग कर सकते हैं, या यह करने के लिए बड़े प्रतिनिधि वाक्य रचना में:

Func<string> fnHello =() => "hello"; 
Console.WriteLine(fnHello()); 

Func<string> fnHello2 = delegate() 
{ 
    return "hello 2"; 
}; 
Console.WriteLine(fnHello2()); 

तो क्यों मैं "इनलाइन" लैम्ब्डा या प्रतिनिधि शरीर, और से बचने पर कब्जा नहीं कर सकते यह एक नामित चर (इसे अनाम बनाते हुए) में?

// Inline anonymous lambda not allowed 
Console.WriteLine(
    (() => "hello inline lambda")() 
); 

// Inline anonymous delegate not allowed 
Console.WriteLine(
    (delegate() { return "hello inline delegate"; })() 
); 

एक उदाहरण है कि जावास्क्रिप्ट (सिर्फ तुलना के लिए) में काम करता है:

alert(
    (function(){ return "hello inline anonymous function from javascript"; })() 
); 

कौन सा उम्मीद चेतावनी बॉक्स पैदा करता है।

अद्यतन: ऐसा लगता है कि आप यह कर सकते हैं सी # में एक इनलाइन गुमनाम लैम्ब्डा है, यदि आप उचित रूप से डाली, लेकिन() के शुरू होने से इसमें लगाई अनियंत्रित बनाने के लिए।

// Inline anonymous lambda with appropriate cast IS allowed 
Console.WriteLine(
    ((Func<string>)(() => "hello inline anonymous lambda"))() 
); 

शायद संकलक गुमनाम प्रतिनिधि के sig अनुमान नहीं लगा सकता पता करने के लिए जो Console.WriteLine() आप कॉल करने के लिए कोशिश कर रहे हैं? क्या किसी को पता है कि इस विशिष्ट कलाकार की आवश्यकता क्यों है?

+0

इस पर विचार करें: 'सार्वजनिक स्थैतिक आर इवल (Func मीटर) {वापसी एम();} '। फिर आप 'Eval (() => {वापसी "परीक्षण";}) कह सकते हैं' जो थोड़ा अच्छा है, या यहां तक ​​कि 'Eval (() => {वापसी "परीक्षण";}) '। – Ben

उत्तर

19

सी # में लैम्बडास के पास प्रकार नहीं हैं, जब तक कि वे किसी संदर्भ में उपयोग नहीं किए जाते हैं जो उन्हें किसी प्रतिनिधि या अभिव्यक्ति प्रकार में डाल देता है। इसलिए आपको यह नहीं कह सकते

var x =() => "some lambda"; 

है आप

http://blogs.msdn.com/ericlippert/archive/2007/01/11/lambda-expressions-vs-anonymous-methods-part-two.aspx

http://blogs.msdn.com/ericlippert/archive/2007/01/12/lambda-expressions-vs-anonymous-methods-part-three.aspx

+0

+1। सी # में लैम्बडास के बारे में महत्वपूर्ण बुनियादी अवधारणा। – Cheeso

2

का आनंद सकता है आप तरीकों कि एक प्रतिनिधि पैरामीटर में ले लिए इनलाइन लैम्ब्डा एक्सप्रेशन का उपयोग कर सकते हैं।

हालांकि मामूली पकड़ है - यदि पैरामीटर बेस प्रतिनिधि प्रकार के रूप में टाइप किया गया है, तो आपको स्पष्ट रूप से इसे प्रतिनिधि (विशिष्ट कार्यवाही) के विशिष्ट व्युत्पन्न पर डालना होगा; अन्यथा संकलक शिकायत करेगा।

इसी प्रकार के प्रश्न:
Anonymous method in Invoke call
Anonymous methods and delegates

8

जब आप Func<string> = ... लिखते हैं, संकलक जानता है कि यह प्रकार Func<string> की एक वस्तु बनाने के लिए है। लेकिन जब आप उस प्रतिनिधि इनलाइन को लिखते हैं, तो संकलक को यह नहीं पता कि किस प्रकार का निर्माण करना है।

उपरोक्त कहने के बाद, एक स्पष्ट निष्कर्ष निकाला जा सकता है: बस संकलक को स्पष्ट रूप से बताएं!

Console.WriteLine(new Func<string>(() => "Hello")()); 

अद्यतन

ठीक है, जब तक मैं इस सवाल का जवाब लिख रहा था, आप अपनी पोस्ट अपडेट किया गया। मेरा मानना ​​है कि उपरोक्त मेरा उत्तर पहले से ही प्रश्न का उत्तर देता है "यह विशिष्ट प्रकार क्यों आवश्यक है"। दोहराने के लिए: क्योंकि संकलक को किस प्रकार का निर्माण करने की वस्तु नहीं पता है।

अब "पर थोड़ा विस्तार करने के लिए संकलक अज्ञात प्रतिनिधि" भाग के सिग का अनुमान नहीं लगा सकता है। आप देखते हैं, यह जावास्क्रिप्ट में पसंद नहीं है। सी # में, कोई सामान्य "फ़ंक्शन" (या "विधि") प्रकार नहीं है। प्रत्येक प्रतिनिधि के पास स्पष्ट रूप से निर्दिष्ट हस्ताक्षर और प्रकार का नाम होना चाहिए। और जब आप एक प्रतिनिधि बना रहे हैं, तो संकलक को पता होना चाहिए कि किस प्रकार का।

अब, मैं देख सकता हूं कि आप कैसे संकेत दे सकते हैं कि कंपाइलर केवल मक्खी पर एक प्रतिनिधि प्रकार का निर्माण कर सकता है, जैसे यह अज्ञात ऑब्जेक्ट प्रकारों (उर्फ new { a = 1, b = "xyz" }) के साथ करता है। लेकिन एक पल के लिए इसके बारे में सोचें: वैसे भी ऐसे प्रतिनिधि के लिए शायद कोई उपयोग नहीं होगा। मेरा मतलब है, आप इसे किसी अन्य विधि में नहीं पारित कर सकते हैं, क्योंकि उस विधि को पहले इसके तर्कों के प्रकार घोषित करना है। और आप इसे से बाहर निकाल सकते हैं, क्योंकि, फिर से, आपके पास एक नाम टाइप होना चाहिए।

कुछ इस तरह ...

11

यह काम करने के लिए यदि आप इसे एक प्रकार डाली देने लगता है:

String s = ((Func<String>) (() => "hello inline lambda"))(); 

यह बेकार है? पूरी तरह से नहीं। नीचे डालें:

String s; 
{ 
    Object o = MightBeNull(); 
    s = o == null ? "Default value" : o.ToString(); 
} 

अब इस पर विचार करें:

String S = ((Func<Object,String>)(o => o == null ? "Default value" : o.ToString()) 
    )(MightBeNull()); 

यह थोड़ा बदसूरत है, लेकिन यह कॉम्पैक्ट है।

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

  • कोई संबंधित समस्या नहीं^_^