创建包含参数的通用 lambda 表达式

Creating a generic lambda expression that includes parameter

简而言之,我正在尝试构建相当于

Call<UnknownRegisteredClass>(r => r.UnknownMethod(...args))

作为 Expression<Action<T> 在运行时通过反射。

表达式的整个概念对我来说很新,但是 everything 我在文档中发现似乎并没有从 generic/reflection 的角度来解决它,而是从更多的角度具有已知类型的建筑表达式。

到目前为止,我已经设法组装了内部表达式 r.UnknownMethod(...args):

Expression.Lambda<Action>(Expression.Call(Expression.New(actionType), actionMethod, parameterExpressions))

但我不确定如何将其包装在另一个级别,该级别实际上是针对 Action<T>

的参数进行调用的

似乎会是这样的:

ParameterExpression instance = Expression.Parameter(typeof(T), "instance");
return Expression.Lambda<Action<T>>(Expression.Call(instance, HowDoIGetMyAboveExpressionHere), new ParameterExpression[] { instance });

但这并没有真正起作用,因为我不能使用 <T>,因为直到运行时我才知道类型。如果有人能看到我正在尝试做的事情并且有任何例子可以指出我,我将非常感激。

我显然非常接近问题结尾处的内容。我创建了一个本地通用方法,该方法将为我 return 表达式,然后我只在运行时调用它:

public Expression<Action<T>> GetActionExpression<T>(Type type, MethodInfo callingMethod, List<Expression> parameterExpressions)
{
    var callLambdaParameter = Expression.Parameter(type, "p");
    var callBody = Expression.Call(callLambdaParameter, callingMethod, parameterExpressions.ToArray());
    return Expression.Lambda<Action<T>>(callBody, callLambdaParameter);
}

然后调用它:

var genericActionExpression = GetType().GetMethod(nameof(GetActionExpression)).MakeGenericMethod(actionType).Invoke(this, new object[] { actionType, actionMethod, parameterExpressions});

然后我就可以使用现在基本上r => r.UnknownMethod(...args)调用所需的方法了:

callMethod.Invoke(this, new[] { Caller, genericActionExpression });