Following code to do a simple property assignment person.Name = "Joe Bloggs" by dynamically creating a method using an Expression Tree fails with a NullReferenceException - it's like the person parameter I create isn't being passed in.
Any ideas?
class Person
{
    public string Name { get; set; }
}
static void ExpressionTest()
{
    var personParam = Expression.Parameter(typeof(Person), "person");
    var block = Expression.Block(new[] { personParam },
        Expression.Assign(
            Expression.Property(personParam, "Name"), Expression.Constant("Joe Bloggs"))
        );
    /* 
        * block.DebugView in debugger shows:
        * 
        *   .Block(MyProject.MyNamepace.Person $person) {
        *       $person.Name = "Joe Bloggs"
        *   }
        *   
        */
    var method = Expression.Lambda<Action<Person>>(block, personParam).Compile();
    var person = new Person();
    method(person); // **throws** System.NullReferenceException: ... at lambda_method(Closure , Person )
    Debug.WriteLine(person.Name); // I expect this to print "Joe Bloggs"
}
Thanks for the great answers, I saw @decPL's first that led me to removing the new[] { personParam } from the Expression.Block call. 
It all makes complete sense that a Block scopes variables and you need to define them first (like some languages force you to) - my problem was that I didn't need any variables but was led astray by the magic DebugView property that the debugger shows you into thinking that they were parameters, and the Block was like a function definition:
.Block(MyProject.MyNamepace.Person $person) {
    $person.Name = "Joe Bloggs"
}
... which of course it isn't. It's a block of code as the name suggests duh!
To clarify, BlockExpression represents a sequence of expressions that are executed sequentially, and returns the value of the last expression.
The version of Expression.Block you are using "creates a BlockExpression that contains the given variables and expressions." (http://msdn.microsoft.com/en-us/library/dd324074(v=vs.110).aspx) hence it creates code:
{
    Person person;
    person.Name = "Joe Bloggs";
}
So it clearly throws NullReferenceException.
It works as expected if you remove the block:
var personParam = Expression.Parameter(typeof(Person), "person");
var method = Expression.Lambda<Action<Person>>(Expression.Assign(
                    Expression.Property(personParam, "Name"), Expression.Constant("Joe Bloggs")), personParam).Compile();
to fix your original code, you should remove the parameter expression passed to the block:
var block = Expression.Block(
                Expression.Assign(
                    propertyExpr, Expression.Constant("Joe Bloggs"))
                );
                        You're passing the parameter of your method to the Expression.Block method as a variable, which it is not. If you remove it, it will work correctly:
var block = Expression.Block(
               Expression.Assign(
                   Expression.Property(personParam, "Name"),
                   Expression.Constant("Joe Bloggs")));
Of course, if that's the extent of your program, you may just as well drop the block expression.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With