2010-07-30 18 views
27

LINQ ifade ağacı inşa ediyorum değişkeni almak için ama iddia edilen yerel değişken $var1 kapsam dışında olduğu için derlenmeyecektir nasıl:bir LINQ ifade ağacı oluşturma: kapsam

değişken ''

.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 
} 
: tip 'System.Object'ten' 'kapsamından başvurulan, ancak bu ifade ağacı

tanımlanmamış ait 10

Aşağıdaki kod ağacı oluşturmaktan sorumludur. Bu, daha büyük bir şeyin bir parçasıdır, bu yüzden amacının bu örnekten açıkça anlaşılmasını beklemiyorum.

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()(); 

Yani soru şu: ifadesi başarıyla derler ki nasıl kapsam içine lokal değişken alabilirim?

cevap

42

Your'e bloğunda "normal" ifadelerinin listesine Expression.Variable ekleyerek - Sen use the overload which specifies the variables do declare for the block separately yapmalıdır:

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

(Ve çağrıyı kaldırmak expressions.Add(resultVariable); kadar)

+0

Teşekkür Jon, o çalıştı! Bunu çözmek, ikinci, oldukça benzer bir sorunu ortaya çıkardı. SourceExpression değişkeninin atanması, ifade derleyicisinin atmasını sağlar: '' TestClass 'türünde' variable 'n', '' kapsamından başvurulan, ancak tanımlanmadı '' –

+0

Bu sorunu giderebildim, tekrar teşekkürler. –

+1

Bana yardım ettiğin için tekrar teşekkürler. Soru, http://blog.subspace.nl/post/Getting-rid-of-null-checks-in-property-chains.aspx adresinde yazdığım bir blog yazısı ile yakından ilgiliydi. –

İlgili konular