2010-10-19 7 views
5

मान लीजिए कि आप निम्नलिखित कोड डालें:एक Linq कथात्मक क्वेरी अभिव्यक्ति में एक लैम्ब्डा सम्मिलित करने के लिए कैसे

string encoded="9,8,5,4,9"; 

    // Parse the encoded string into a collection of numbers 
    var nums=from string s in encoded.Split(',') 
      select int.Parse(s); 

आसान है यही कारण है, लेकिन क्या अगर मैं चयन में करने के लिए एक लैम्ब्डा अभिव्यक्ति लागू करना चाहते हैं, लेकिन अभी भी इसे एक घोषणात्मक क्वेरी अभिव्यक्ति के रूप में रखें, दूसरे शब्दों में:

string encoded="9,8,5,4,9"; 

    // Parse the encoded string into a collection of numbers 
    var nums=from string s in encoded.Split(',') 
      select (s => {/* do something more complex with s and return an int */}); 

यह निश्चित रूप से संकलित नहीं होता है। लेकिन, मैं इसे तरल वाक्यविन्यास में स्विच किए बिना वहां एक लैम्ब्डा कैसे प्राप्त कर सकता हूं।

अद्यतन: StriplingWarrior से मार्गदर्शन के लिए धन्यवाद, मैं एक जटिल लेकिन compilable समाधान है:

var result=from string s in test.Split(',') 
      select ((Func<int>) 
      (() => {string u="1"+s+"2"; return int.Parse(u);}))(); 

कुंजी का चयन में से प्रत्येक यात्रा के लिए लैम्ब्डा के मूल्यांकन के बाद एक Func<string,int> को इस फिल्म में है (s) के साथ। क्या कोई भी कुछ भी आसान के साथ आ सकता है (यानी, फनक के कलाकारों के मूल्यांकन के बाद या शायद कुछ कम वर्बोज़ जो प्रश्न अभिव्यक्ति वाक्यविन्यास को बनाए रखते हुए एक ही अंतिम परिणाम प्राप्त करता है)?

नोट: उपरोक्त लैम्ब्डा सामग्री प्रकृति में मामूली और अनुकरणीय है। कृपया इसे मत बदलें।

अद्यतन 2: हाँ, यह मैं हूँ, पागल माइक, वापस एक वैकल्पिक साथ (खूबसूरत?) इस का हल:

public static class Lambda 
{ 
    public static U Wrap<U>(Func<U> f) 
    { 
    return f(); 
    } 
} 
... 
    // Then in some function, in some class, in a galaxy far far away: 

    // Look what we can do with no casts 
    var res=from string s in test.Split(',') 
      select Lambda.Wrap(() => {string u="1"+s+"2"; return int.Parse(u);}); 

मैं इस बदसूरत कास्ट और parenarrhea बिना समस्या का हल है। क्या Lambda की तरह कुछ है। जेड जेनेरिक विधि पहले से ही .NET 4.0 फ्रेमवर्क में मौजूद है, ताकि मुझे पहिया को फिर से शुरू करने की आवश्यकता न हो? इस चर्चा को अधिक परेशान नहीं करने के लिए, मैंने इस बिंदु को अपने प्रश्न में स्थानांतरित कर दिया है: Does this "Wrap" generic method exist in .NET 4.0

select DoSomethingComplex(s) 

आप तरीकों को पसंद नहीं करते हैं, तो आप इस्तेमाल कर सकते हैं एक समारोह:

+1

मुझे समझ नहीं आता क्यों क्या कभी किसी ने कथात्मक वाक्यविन्यास का उपयोग करना चाहते हैं। एसक्यूएल के साथ इसकी समानता नए आने वालों को लिनक्स में भ्रमित करने लगती है, इससे उन्हें यह समझने में मदद मिलती है कि लिनक क्या है। लेकिन वैसे भी अच्छा सवाल है। +1 –

+1

@klausbyskov, SO पर "क्यों" के बारे में कई सवाल हैं जिनका उत्तर दिया गया है। मैं इस सवाल में क्यों संबोधित करने से कम चिंतित हूं और यदि संभव हो तो "कैसे" का जवाब देना चाहता हूं। माना जाता है कि मेरा उदाहरण धाराप्रवाह वाक्यविन्यास के लिए सबसे अच्छा उम्मीदवार नहीं है, लेकिन मैं एक साधारण उदाहरण का उपयोग करना चाहता था ताकि मेरे प्रश्न को खत्म न किया जा सके। –

+1

घोषणात्मक वाक्यविन्यास आसान है जब आपके पास एकाधिक 'जॉइन' या 'से' होता है, जो अन्यथा कुछ गन्दा हाथ-कोडित अनाम प्रकारों की आवश्यकता होती है। – StriplingWarrior

उत्तर

2

आप वस्तुओं को LINQ का उपयोग कर रहे मान लिया जाये, तो आप सिर्फ एक सहायक विधि इस्तेमाल कर सकते हैं

Func<string, string> f = s => { Console.WriteLine(s); return s; }; 
var q = from string s in new[]{"1","2"} 
     select f(s); 

या यदि आप पूरी तरह से तुली यह इनलाइन डाल रहे हों, तो कुछ इस तरह कर सकता है:

from string s in new[]{"1","2"} 
select ((Func<string>)(() => { Console.WriteLine(s); return s; }))() 
+0

{} ब्रेसिज़ का उपयोग करके, आप प्रभावी ढंग से कह रहे हैं कि आपकी लैम्ब्डा अभिव्यक्ति एक फ़ंक्शन का प्रतिनिधित्व करती है। – StriplingWarrior

+0

मुझे लगता है कि आप उत्तर पर हैं। कुंजी लैम्ब्डा अभिव्यक्ति के Func (स्ट्रिंग नहीं) में डाली गई है। मुझे इसके साथ थोड़ा और खेलने दें, लेकिन आपका जवाब सही रास्ते पर है, इसलिए अब के लिए +1 ... –

+1

हां, 'Func ' में टी को अभिव्यक्ति से * प्राप्त करने की अपेक्षा की जाने वाली किसी भी प्रकार की आवश्यकता है । उनका उदाहरण 'स्ट्रिंग' का उपयोग करता है क्योंकि वह दिन के अंत में बस 's' वापस कर रहा है। –

0

आप बस कर सकता है:

var nums = from string s in encoded.Split(',') 
      select (s => { DoSomething(); return aValueBasedOnS; }); 

रिटर्न संकलक को परिणामी संग्रह के प्रकार को बताता है।

+0

मैंने इस तरह कुछ करने की कोशिश की, लेकिन यह संकलित नहीं होगा: var nums = test में स्ट्रिंग एस से। स्प्लिट ('_') चुनें {t => {int n = DoSomething (t); ... वापसी एन;}}; // कहां कुछ समझा जाता है: int DoSomething (string s) ... –

+0

उपर्युक्त अभिव्यक्ति में सुधार (अभी भी संकलित नहीं होगा): var result = test में स्ट्रिंग से। स्प्लिट ('_') चुनें (t => {वापसी int.Parse (DoSomething (टी));}); –

0

कैसे इस बारे में:

var nums= (from string s in encoded.Split(',') select s).Select(W => ...); 
0

किसी को भी कुछ भी सरल के साथ आ सकते हैं?

हां।सबसे पहले, आप यह इस

var result = from s in encoded.Split(',') 
      select ((Func<int>)(() => int.Parse("1" + s + "2")))(); 

हालांकि तरह पुनर्लेखन कर सकता है, जो वास्तव में पढ़ने योग्य नहीं है, विशेष रूप से एक प्रश्न अभिव्यक्ति के लिए। इस विशेष क्वेरी और प्रक्षेपण के लिए, let कीवर्ड का उपयोग किया जा सकता है।

var result = from s in encoded.Split(',') 
      let t = "1" + s + "2" 
      select int.Parse(t); 
+0

मुझे बीच में जाने की कोई बात नहीं है, लेकिन मैं वहां "लैम्ब्डा अभिव्यक्ति" कैसे प्राप्त करूं, न कि "1" + s + "2"। यह सिर्फ एक उदाहरण था ... –

+0

वैसे ही आप 'चयन' के लिए करेंगे। जैसे 'चलो टी = ((Func ) (() => "1" + एस + "2"))() '। दोबारा, यदि आप और अधिक करना चाहते हैं तो यह मामूली रूप से अपठनीय के क्षेत्र में वापस आ गया है, और मोरेसो। मैं एक बार फिर से कहता हूं कि आपका प्रश्न/टिप्पणियां मुझे परेशान करती हैं कि आपका * असली * इरादा क्या है। –

+0

@ माइकल, नीचे की रेखा यह है कि क्वेरी अभिव्यक्ति वाक्यविन्यास का उपयोग करते समय, आपको अभिव्यक्ति के लिए जो कुछ भी 'Func <> 'लागू होता है, उसे कास्ट करके आपके लैम्ब्डा के बारे में संकलक को बताना होगा। आपको अभिव्यक्ति का आह्वान करने की आवश्यकता होगी, हालांकि कई पैरामीटर उपयुक्त हैं।लेकिन मैं रिकॉर्ड के लिए बस कहना चाहूंगा: बहुत सावधान रहें। –

0

IEnumerable पूर्णांकों = encoded.Split (',') का चयन करें (रों => int.Parse (रों))।

संपादित करें:

IEnumerable<int> integers = from s in encoded.Split(',') select int.Parse(string.Format("1{0}2",s)); 
+0

मुझे लगता है कि आप प्रश्न के बिंदु को याद करते हैं, जो 'कॉलिंग' से बचने के लिए था। चयन करें (...) ' – StriplingWarrior

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