Use lambda return value for expression tree

c# expression-trees lambda

Question

I try to play a bit with expression trees. I have an object with a List<string> and I want to build an expression tree that add a value to this property, but I want to specify the value to add through a Func. Currently I try this...

public static Action<T> CreateMethodAddObjectToList<T, C>(this Type type, string property, Func<C> ctorFunction)
        {
            PropertyInfo fieldInfo = type.GetProperty(property);

            if (fieldInfo == null)
            {
                return null;
            }

            ParameterExpression targetExp = Expression.Parameter(type, "target");
            MemberExpression fieldExp = Expression.Property(targetExp, property);
            var method = fieldExp.Type.GetMethod("Add", BindingFlags.Public | BindingFlags.Instance);

            Expression<Func<C>> ctorExpression = () => ctorFunction();

// but this doesnt work because I can't use the ctorExpression in this way
            var callExp = Expression.Call(fieldExp, method, ctorExpression);

            var function = Expression.Lambda<Action<T>>(callExp, targetExp).Compile();

            return function;
        }

the call looks like

var dummyObject = new DummyObject { IntProperty = 5 };

            Action<DummyObject> setter = typeof (DummyObject).CreateMethodAddObjectToList<DummyObject, string>("StringList", () => "Test" );

Accepted Answer

You can change ctorFunction to an Expression<Func<C>> and then invoke it in the generated action:

public static Action<T> CreateMethodAddObjectToList<T, C>(this Type type, string property, Expression<Func<C>> createExpr)
{
    PropertyInfo fieldInfo = type.GetProperty(property);

    if (fieldInfo == null)
    {
        return null;
    }

    ParameterExpression targetExp = Expression.Parameter(type, "target");
    MemberExpression fieldExp = Expression.Property(targetExp, property);
    var method = fieldExp.Type.GetMethod("Add", BindingFlags.Public | BindingFlags.Instance);

    var valueExpr = Expression.Invoke(createExpr);
    var callExpr = Expression.Call(fieldExp, method, valueExpr);

    var function = Expression.Lambda<Action<T>>(callExpr, targetExp).Compile();

    return function;
}


Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why
Licensed under: CC-BY-SA with attribution
Not affiliated with Stack Overflow
Is this KB legal? Yes, learn why