对表达式树使用 lambda 返回值

本文关键字:lambda 返回值 表达式 | 更新日期: 2023-09-27 18:32:50

我尝试使用表达式树。我有一个带有List<string>的对象,我想构建一个表达式树,为此属性添加一个值,但我想指定要通过Func添加的值。目前我尝试这个...

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

呼叫看起来像

var dummyObject = new DummyObject { IntProperty = 5 };
            Action<DummyObject> setter = typeof (DummyObject).CreateMethodAddObjectToList<DummyObject, string>("StringList", () => "Test" );

对表达式树使用 lambda 返回值

您可以将 ctorFunction 更改为Expression<Func<C>>,然后在生成的操作中调用它:

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