如何从Lambda表达式的字符串动态创建方法

本文关键字:字符串 动态 创建 方法 表达式 Lambda | 更新日期: 2023-09-27 18:26:44

我的最终目标是创建一个函数,该函数将动态地将方法名称传递给Hangfire库中的类。

例如,以下是工作的非动态代码:

RecurringJob.AddOrUpdate(() => myFunction(), Cron.Hourly)

AddOrUpdate的第一个参数的类型为Expression<Action>。我的第一步是使用反射来动态插入函数名:

Type thisControllerType = this.GetType();
MethodInfo method = thisControllerType.GetMethod(methodName); //methodName passed as string parameter
RecurringJob.AddOrUpdate(() => method.Invoke(this, null), Cron.Hourly);

当我查看Hangfire面板时,这个表达式似乎被计算为MethodBase.Invoke。因此,我需要动态传递方法名称的帮助。

这可能足以回答我的问题,但我所采取的另一条途径是尝试生成论点的整个表达式。

RecurringJob.AddOrUpdate(CreateCallExpression(method), Cron.Hourly);
public Expression<Action> CreateCallExpression(MethodInfo method)
    {
        //trying to pass in zero argument parameter, not sure if this syntax is correct    
        var parameter = System.Linq.Expressions.Expression.Parameter(typeof (Array));
        return System.Linq.Expressions.Expression.Lambda<Action>(System.Linq.Expressions.Expression.Call(method, parameter));
    }

在这种情况下,我得到了异常{"静态方法需要null实例,非静态方法需要非null实例。''r''n参数名称:method"}。我正在努力,但不确定这是否是我应该走的路。我已经做了一整天了,所以我希望有人能帮助我加快学习速度。

如何从Lambda表达式的字符串动态创建方法

您的第二个实例将用于创建指向指定方法的指针,但要解决静态问题,您只需要用以下两种方法之一修改以下行。首先,您可以通过声明您寻求的方法是静态的并修改这行代码来完成静态引用:

System.Linq.Expressions.Expression.Call(method, parameter);

您必须为调用方法提供一个null参数,因为如果您正在搜索一个静态方法,那么编译器将确切地知道您想要什么方法签名,因为只存在1。代码行将更新为:

System.Linq.Expressions.Expression.Call(null, method, parameter); 

第二种方法是定义与方法相关的类或"实例",以便编译器知道要针对哪个类搜索方法签名。你必须这样修改你的代码:

var myInstance = Expression.Parameter(typeof(MyClass), "inst");
System.Linq.Expressions.Expression.Call(myInstance, method, parameter)

我建议您查看Call的文档,以便准确地了解指针是如何创建的。