I have a parser that builds a list of variables and a list of expressions.
I put those into a block expression and compile ...

var blk = Expression.Convert(Expression.Block(Parser.m_Vars, Parser.m_Expr),typeof(CVar));
            var expr = Expression.Lambda<Func<CVar>>(blk);
            var result = "";

               var actionX = expr.Compile();
               result = actionX();

The resulting tree looks like this ...

.Lambda #Lambda1<System.Func`1[CVar]>() {
        CVar $Test1,
        CVar $Test2) {
        $Test1 = (CVar)"Foo ";
        $Test2 = (CVar)"Bar ";
        $Test1 + $Test2

The compile method throws an exception "variable 'Test1' of type 'CVar' referenced from scope '', but it is not defined".

If I build an identical tree in code ...

var exprs = new List<Expression>();
            var vars = new List<ParameterExpression>();

            vars.Add(Expression.Parameter(typeof(CVar), "Test1"));
            vars.Add(Expression.Parameter(typeof(CVar), "Test2"));
            exprs.Add(Expression.Assign(vars[0], Expression.Convert(Expression.Constant("Foo "), typeof(CVar))));
            exprs.Add(Expression.Assign(vars[1], Expression.Convert(Expression.Constant("Bar "), typeof(CVar))));
            exprs.Add(Expression.Add(vars[0], vars[1]));

            var blk1 = Expression.Convert(Expression.Block(vars, exprs), typeof(CVar));
            var expr1 = Expression.Lambda<Func<CVar>>(blk1);
            var action1 = expr1.Compile();

            var result1 = action1();

It works like it's supposed to.

Both trees are identical as far as I can tell in the 2010 debug visualizer and in the old 2008 visualiser.

I'm at a loss.

Yes! I figured it out!

When the parser first encounters a variable it defines & assigns it

var p1 = Expression.Parameter(typeof(CVar), "Test1"));
   m_exprs.Add(Expression.Assign(p1, Expression.Convert(Expression.Constant("Foo "), typeof(CVar))));

Later when it's used a parameter expression is created for the reference ...

var p1 = Expression.Parameter(typeof(CVar), "Test1"));
   var p2 = Expression.Parameter(typeof(CVar), "Test2"));

   m_exprs.Add(Expression.Add(p1, p2));

This cannot be done! You MUST use the original ParameterExpression created above!

var p1 = GetVariable("Test1"));
   var p2 = GetVariable("Test2"));

   m_exprs.Add(Expression.Add(p1, p2));

I don't understand why it would be that way, it's just an expression. But I guess there is a reason. It would allow you to manage unnamed variables I suppose.

Anyways, Woot!

This question has already been answered. Start a new discussion instead.