2010-07-30 17 views
27

मैं एक LINQ अभिव्यक्ति पेड़ के निर्माण कर रहा हूँ में चर प्राप्त करने के लिए, लेकिन यह संकलन नहीं करेगा क्योंकि कथित तौर पर स्थानीय चर $var1 दायरे से बाहर है:एक LINQ अभिव्यक्ति पेड़ का निर्माण: कैसे गुंजाइश

चर ''

.Block() { 
    $var1; 
    .If ($n.Property1 == null) { 
     .Block() { 
      $var1 = null; 
      .Return #Label1 { } 
     } 
    } .Else { 
     .Default(System.Void) 
    }; 
    $var1 = (System.Object)($n.Property1).Length; 
    .Label 
    .LabelTarget #Label1:; 
    $var1 
} 
: प्रकार 'System.Object' गुंजाइश 'से' संदर्भित है, लेकिन यह निर्धारित नहीं है

यह अभिव्यक्ति का पेड़ है की 10

निम्नलिखित कोड पेड़ के निर्माण के लिए ज़िम्मेदार है। यह कुछ बड़ा हिस्सा है, इसलिए मुझे इस उद्देश्य से पूरी तरह से स्पष्ट होने की उम्मीद नहीं है।

MemberExpression sourceExpression = ...; 

List<Expression> expressions = new List<Expression>(); 
LabelTarget returnTarget = Expression.Label(); 
ParameterExpression resultVariable = Expression.Variable(typeof(object)); 

expressions.Add(resultVariable); 

expressions.Add(
    Expression.IfThen(
     Expression.Equal(sourceExpression, Expression.Constant(null)), 
     Expression.Block(
      Expression.Assign(resultVariable, Expression.Constant(null)), 
      Expression.Return(returnTarget)))); 

expressions.Add(
    Expression.Assign(
     resultVariable, 
     Expression.Convert(sourceExpression, typeof(object)))); 

expressions.Add(Expression.Label(returnTarget)); 
expressions.Add(resultVariable); 

Expression finalExpression = Expression.Block(expressions); 
object result = Expression.Lambda<Func<object>>(finalExpression).Compile()(); 

तो सवाल यह है कि: मैं स्थानीय चर को दायरे में कैसे प्राप्त करूं ताकि अभिव्यक्ति सफलतापूर्वक संकलित हो सके?

उत्तर

42

Your'e ब्लॉक में "सामान्य" अभिव्यक्ति की सूची में Expression.Variable जोड़ने - आपको चाहिए use the overload which specifies the variables do declare for the block separately:

Expression finalExpression = Expression.Block(new[] { resultVariable }, 
               expressions); 

(और कॉल को दूर करने के लिए expressions.Add(resultVariable);)

+0

धन्यवाद जॉन, कि काम किया! इसे हल करने से एक दूसरा, बल्कि इसी तरह का मुद्दा सामने आया। SourceExpression वैरिएबल का असाइनमेंट अभिव्यक्ति कंपाइलर फेंक बनाता है: "चर 'से' टेस्ट क्लास 'प्रकार का' चर '' ', लेकिन यह परिभाषित नहीं किया गया है" –

+0

मैं उस समस्या को ठीक करने में सक्षम था, धन्यवाद। –

+1

मेरी मदद करने के लिए फिर से धन्यवाद। यह प्रश्न उस ब्लॉग पोस्ट से निकटता से संबंधित था जो मैं http://blog.subspace.nl/post/Getting-rid-of-null-checks-in-property-chains.aspx पर लिख रहा था जो ब्याज की हो सकती है। –

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