如何从Lambda表达式的String动态创建方法

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

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

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

AddOrUpdate的第一个参数的类型是Expression 。 我的第一步是使用reflection来动态插入函数名称:

 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 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(System.Linq.Expressions.Expression.Call(method, parameter)); } 

在这种情况下,我得到exception{“静态方法需要空实例,非静态方法需要非空实例。\ r \ n \参数名称:方​​法”}。 我正在努力,但不确定这是否应该是我应该走的路。 我一整天都在努力,所以我希望有人可以帮助我加快学习速度。

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

 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的文档,以便确切知道指针的创建方式。