Search code examples
c#expression-trees

Assign value to property via expression-tree


I want to implement an expression-tree for assignment-calls to properties of my model. So I am able to call it like this:

UpdateFeature(myFeature, x => x.MyProperty, "newValue"); 

which would set the myFeature.MyProperty to "newValue".

myFeature is of type MyType:

class MyType 
{ 
    public string MyProperty { get; set; } 
}

My UpdateFeature-function is this:

void UpdateFeature<T, TResult>(T feature, Expression<Func<T, TResult>> e, TResult newValue)
{
    Expression exp = Expression.Assign((MemberExpression)e.Body, Expression.Constant(newValue));
    var lambda = Expression.Lambda(exp, Expression.Parameter(typeof(T)));
    lambda.Compile().DynamicInvoke(feature);
}

However I get an InvalidOperationException when calling Compile:

variable 'x' of type 'MyType' referenced from scope '', but it is not defined

I also tried using strongly-typed lambda:

var lambda = Expression.Lambda<Action<T>>(exp, Expression.Parameter(typeof(T)));

with the exact same error appearing.


Solution

  • Try the following simplified version.

    void UpdateFeature<T, TResult>(T feature, Expression<Func<T, TResult>> e, TResult newValue)
    {
        var x = e.Parameters[0];
        var exp = Expression.Assign(e.Body, Expression.Constant(newValue));
        var lambda = Expression.Lambda<Action<T>>(exp, x);
        lambda.Compile()(feature);
    }
    

    Anyway calling this method is ineffective. Compiling lambda takes a lot of time. Without caching compiled methods, better to use just reflection.