Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Building a LINQ expression tree: how to get variable in scope

I'm building a LINQ expression tree but it won't compile because allegedly the local variable $var1 is out of scope:

variable '' of type 'System.Object' referenced from scope '', but it is not defined

This is the expression tree:

.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 } 

The following code is responsible for building the tree. It is part of something larger, therefore I don't expect its purpose to be perfectly clear from this example.

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

So the question is: how do I get the local variable into scope so that the expression compiles succesfully?

like image 514
Sandor Drieënhuizen Avatar asked Jul 30 '10 11:07

Sandor Drieënhuizen


1 Answers

Your'e adding the Expression.Variable to the list of "normal" expressions in the block - you should use the overload which specifies the variables do declare for the block separately:

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

(And remove the call to expressions.Add(resultVariable);)

like image 153
Jon Skeet Avatar answered Oct 14 '22 09:10

Jon Skeet