【问题标题】:Creating a generic lambda expression that includes parameter创建包含参数的通用 lambda 表达式
【发布时间】:2021-12-24 07:22:19
【问题描述】:

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

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

作为Expression&lt;Action&lt;T&gt; 在运行时通过反射。

表达式的整个概念对我来说是相当新的,但是everything 我在文档中发现似乎并没有从通用/反射的角度来解决它,而只是从更多具有已知类型的构建表达式.

到目前为止,我已经成功构建了内部表达式r.UnknownMethod(...args)

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

但我不确定如何将其包装在另一个级别,实际上是针对 Action&lt;T&gt; 的参数进行调用的

好像是这样的:

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

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

【问题讨论】:

  • 但是..泛型是编译时的事情,而不是运行时的事情..
  • 您说您希望将其作为Expression&lt;Action&lt;T&gt;&gt;,所以我希望您要构建的表达式采用T 类型的参数并返回void。这显然不是您显示的Call(...) 表达式的情况。 T类型的参数在哪里?
  • @CaiusJard 是的,该方法是通用的。但我需要在运行时调用它。 @Sweeper 我需要调用的方法的信号是void Call&lt;T&gt;(Expression&lt;Action&lt;T&gt;&gt; methodCall); 只需在 T 上提供一个它应该调用的方法。但是我需要能够在运行时在给定请求的情况下执行此操作,所以我使用 MakeGenericMethod(...) 和我得到的类型,因为我有 MethodInfo 但我只是不确定如何构建那个 Expression>传入。我有一个示例,我可以将其作为 Action 执行,但我需要它在 Action 中提供的第一个参数上调用它。

标签: c# generics lambda


【解决方案1】:

我显然与我在问题结束时的内容非常接近。我创建了一个本地泛型方法,它将为我返回表达式,然后我只在运行时调用它:

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 =&gt; r.UnknownMethod(...args) 来调用所需的方法:

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

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-06-21
    • 2020-07-30
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多