2010-03-01 18 views
8

मैं कैसे इन की तरह दो लैम्ब्डा भाव शामिल होने के बारे जाना होगा: इस तरहमें शामिल होने से लैम्ब्डा भाव

Expression<Func<string, bool>> expr1 = a => a.Length > 100; 
Expression<Func<string, bool>> expr2 = b => b.Length < 200; 

... एक अभिव्यक्ति में:

Expression<Func<string, bool>> expr3 = s => s.Length < 100 && s.Length < 200; 

यही है, उन्हें एक andalso ऑपरेटर के साथ शामिल होने के । (या उस मामले के लिए कोई अन्य ऑपरेटर ...)

मैं वास्तव में लैम्ब्डा पैरामीटर के कुछ बुरा रिकर्सिव प्रतिस्थापन के साथ सफल हुआ और फिर अभिव्यक्ति के साथ जुड़ रहा था। और भी विधि। लेकिन मैं कुछ और आसान खोज रहा हूँ।

कुछ की तरह

उदाहरण के लिए: (। कौन सा स्पष्ट रूप से काम नहीं करता है)

Expression<Func<string, bool>> expr3 = c => expr1(a) && expr2(b); 
+0

बस, सोच क्यों नहीं आप उपयोग कर सकते हैं अभिव्यक्ति > expr3 = s => s.Length <100 && s.Length <200 ;? –

+0

ऐसा इसलिए है क्योंकि अभिव्यक्ति सिस्टम में सेटिंग्स के आधार पर उत्पन्न होती है। मुझे वास्तव में अभिव्यक्तियों की एक सूची में एक अंतिम अभिव्यक्ति में शामिल होने की आवश्यकता है। – LaZe

उत्तर

2

काम करेगा अगर आप सामान्य प्रतिनिधियों के साथ काम कर रहे थे आपका "की तरह कुछ"। लेकिन अगर आपको अभिव्यक्ति पेड़ का उपयोग करना है, तो मुझे रिकर्सिव प्रतिस्थापन की तुलना में कोई अन्य समाधान नहीं दिख रहा है।

.NET 4 में, आप System.Linq.Expressions.ExpressionVisitor का उपयोग इस प्रकार के रिकर्सिव प्रतिस्थापन को अधिक आसान बनाने के लिए कर सकते हैं। .NET 3.5 के लिए, इस नमूने पर एक नज़र डालें: http://msdn.microsoft.com/en-us/library/bb882521.aspx

अभिव्यक्तिविज्ञानी का उपयोग करके, आपको नोड प्रकारों के लिए विधियों को ओवरराइड करना होगा जिन्हें आप प्रतिस्थापित करना चाहते हैं और आसपास के पेड़ को स्वचालित रूप से पुनर्निर्मित किया जाएगा।

यदि आप LINQ के साथ उपयोग के लिए शर्तों से निपट रहे हैं, तो गतिशील रूप से परिस्थितियों को गठबंधन करने का एक आसान समाधान केवल() कई बार कॉल करना है।

+0

मैंने अभी जांच की है और अभिव्यक्तिविज्ञानी इसके लिए बहुत अच्छा काम करता है। 4.0 जारी होने के लिए शायद ही इंतजार कर सकते हैं। – LaZe

1

मैंने अभी खोज की है कि एक नई अद्यतन विधि का उपयोग कर .NET 4 के साथ ऐसा कैसे करें। चूंकि यह एक नई विधि है, मुझे लगता है कि उन्हें इसकी भी आवश्यकता होनी चाहिए। मैं इसके साथ वास्तव में खुश हूं, क्योंकि मेड .NET 3.5 समाधान वास्तव में बदसूरत है। (नोट:। यह समाधान वैसे भी काम नहीं करता है टिप्पणी की जाँच करें।)

Expression<Func<string, bool>> expr1 = a => a.Length > 100; 
Expression<Func<string, bool>> expr2 = b => b.Length < 200; 

// This produces a new expression where the parameter b is replaced with a 
expr2 = expr2.Update(expr1.Body, expr1.Parameters); 

// So now we can join the bodies and produce a new lambda expression. 
Expression<Func<string, bool>> expr3 = Expression.Lambda<Func<string, bool>>(Expression.AndAlso(expr1.Body, expr2.Body), expr1.Parameters); 
+0

मुझे लगता है कि आप गलत समझते हैं कि अद्यतन क्या करता है। यह केवल एक ही प्रकार, नाम और tailcall विकल्पों के साथ एक नया LambdaExpression बनाता है लेकिन एक अलग शरीर और पैरामीटर सेट के साथ। यह lamdba निकायों के भीतर कोई प्रतिस्थापन नहीं करता है। अपना नमूना कोड आउटपुट "ए => ((ए। लम्बाई> 100) और इसके अलावा (ए। लम्बाई> 100))" expr3 के लिए, जो आप नहीं चाहते हैं। – Daniel

+0

अफसोस की बात है कि आप सही डैनियल हैं ... इसलिए मैं अपने ग़लत समाधान पर वापस आ गया हूं :-( – LaZe

2

यह Expression.Invoke साथ बहुत बुरा नहीं है ...:

var strings = (new [] { "a", "bb", "ccc", "dddd", "eeeee", "fffff" }); 
Expression<Func<string, bool>> expr1 = a => a.Length > 1; 
Expression<Func<string, bool>> expr2 = b => b.Length < 4; 

ParameterExpression p = expr1.Parameters[0]; 

var andAlso = System.Linq.Expressions.Expression.AndAlso(Expression.Invoke(expr1, p), Expression.Invoke(expr2, p)); 
var lambda = LambdaExpression.Lambda<Func<string, bool>>(andAlso, p); 
var filteredStrings = strings.AsQueryable().Where(lambda); 
+0

सुझाव रिचर्ड के लिए धन्यवाद। मैं उस विचार को देखूंगा। चूंकि मैं अभिव्यक्तियों को एसक्यूएल में परिवर्तित करता हूं (अन्य चीजों के साथ) मैं ' मुझे अपने सिस्टम में कई जगहों पर InvokeExpression का समर्थन करने की आवश्यकता होगी। यह मेरे वर्तमान समाधान की तुलना में अच्छा है ... – LaZe

+0

मुझे एहसास हुआ कि यह मुझे थोड़ी देर पहले एक समस्या का समाधान करने में मदद कर सकता था और पूरी तरह से अटक गया था .... चीयर्स! –

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