2011-05-24 8 views
8

मैं System.Linq.ExpressionsMemberExpression: InvalidOperationExpression चर 'एक्स' गुंजाइश 'से' संदर्भित, लेकिन

उपयोग कर रहा हूँ मैं एक साधारण LambdaExpression कि एक MemberExpression शामिल निर्माण करने के लिए प्रयास कर रहा था यह परिभाषित नहीं है। यदि मैं SystemELpression को System.Linq.Expressions API (उदाहरण के लिए MakeMemberAccess) के साथ स्पष्ट रूप से बनाता हूं, तो मुझे त्रुटि "अमान्यऑपरेशन एक्स्पेरियन वेरिएबल 'एक्स' स्कोप से संदर्भित 'त्रुटि मिलेगी, लेकिन यह परिभाषित नहीं है" जब मैं संकलन() पर कॉल करता हूं LambdaExpression।

उदाहरण के लिए, यह मेरा कोड

Expression<Func<Customer, string>> expression1, expression2, expression3; 
Func<Customer, string> fn; 
expression1 = (x) => x.Title; 
fn = expression1.Compile();//works 
fn(c); 
MemberExpression m; 
m = Expression.MakeMemberAccess(
Expression.Parameter(typeof(Customer), "x"), typeof(Customer).GetProperty("Title")); 
expression2 = Expression.Lambda<Func<Customer, string>>(m, 
    Expression.Parameter(typeof(Customer), "x")); 

m = Expression.Property(Expression.Parameter(typeof(Customer),"x"), "Title"); 
expression3 = Expression.Lambda<Func<Customer, string>>(m, 
    Expression.Parameter(typeof(Customer), "x")); 

fn = expression3.Compile();//InvalidOperationExpression variable 'x' referenced from scope '', but it is not defined 
fn = expression2.Compile();//InvalidOperationExpression variable 'x' referenced from scope '', but it is not defined 

expression2 है और expression3 एक अपवाद जब संकलित() विधि कहा जाता है फेंक, लेकिन expression1 नहीं करता है, अभिव्यक्ति 1 काम करता है। ऐसा क्यों है? जब मैं संकलन() को कॉल करता हूं तो मैं अभिव्यक्ति 2, 3 में एक सदस्य एक्स्प्रेशन कैसे बना सकता हूं और उन्हें काम करने के लिए (अपवाद फेंक नहीं सकता)?

धन्यवाद

उत्तर

14

आप अलग मानकों "x" कई बार कहा जाता है बना रहे हैं। यदि आप एक ParameterExpression का उपयोग करते हैं, तो यह सब ठीक काम करना चाहिए।

ParameterExpression p = Expression.Parameter(typeof(Customer), "x"); 
MemberExpression m = Expression.MakeMemberAccess(p, 
    typeof(Customer).GetProperty("Title")); 
expression2 = Expression.Lambda<Func<Customer, string>>(m, p); 

m = Expression.Property(p, "Title"); 
expression3 = Expression.Lambda<Func<Customer, string>>(m, p); 

fn = expression3.Compile(); 
fn = expression2.Compile(); 

मूल रूप से पैरामीटर अभिव्यक्तियों का नाम मिलान नहीं होता है - आपको हर जगह एक ही उपयोग करना होगा। यह दर्द का थोड़ा सा है, लेकिन वहां हम जाते हैं ...

+0

वह था, धन्यवाद। –

+0

इस उत्तर के लिए धन्यवाद। –