【问题标题】:c# dynamic invoke method with expression-trees时间:2018-08-10 标签:c#dynamic invoke method with expression-trees
【发布时间】:2015-02-13 17:19:37
【问题描述】:

我正在编写一个小表达式解析器,并希望包含方法调用。 语法类似于:functionName('stringValue',intValue)

然后,表达式解析器应该使用正确的签名(在本例中为字符串,int)查找名为“functionName”的静态函数

解析表达式没问题,但是我在调​​用right方法时遇到了麻烦。

到目前为止,我想出的是一个简单的 Expression.Call:

Expression.Call(typeof(MyContext).GetMethod(functionName), parameterExpressions)

这很好用,以后可以编译成一个可调用的函数。 但是当许多不同的重载、默认参数、params 关键字等开始发挥作用时,它就会变得棘手。我不会重新实现重载解析的整个 C# 逻辑,并认为 DLR 可以帮助我。

使用我可以写的动态关键字:

dynamic myC = MyContext;
return myC.functionName(param1, param2);

DLR 会确定要调用哪个函数重载。

问题是,我如何以编程方式实现这一目标?

到目前为止,我没有运气

Expression.Dynamic(..)

【问题讨论】:

  • 你知道参数的类型吗?

标签: c# dynamic expression-trees


【解决方案1】:

GetMethod 有一个重载,只要您知道类型,它就会为您执行重载解析。同样,Expression.Call() 也有一个重载,它采用方法名称和类型。

// Assuming you have parameter expressions with known types...
string functionName = "functionName";
ParameterExpression param1 = Expression.Parameter(typeof(string), "stringValue");
ParameterExpression param2 = Expression.Parameter(typeof(int), "intValue");
var parameterExpressions = new ParameterExpression[] { param1, param2};

// Extract the types...
Type[] parameterTypes = parameterExpressions.Select(p => p.Type).ToArray();

// This will do the overload resolution and give you the methodInfo
MethodInfo methodToCall = typeof(Robot).GetMethod(
    functionName,
    parameterTypes);
Expression e = Expression.Call(methodToCall, parameterExpressions);

【讨论】:

  • 我确实知道参数类型(在运行时),所以这听起来很有希望!明天试试
  • 我只关注 GetMethods 重载,从未关注 GetMethod!谢谢你的帮助
  • 仔细观察,这只会处理重载,但在存在例如的情况下不提供重载解决方案。默认参数。
  • 采用类型数组的Expression.Call 的重载不会对被调用的方法进行重载解析 - 如果方法是泛型的,则该数组严格用于指定泛型类型参数。如果你想做重载解析,你必须通过GetMethod (如果你想自定义它的工作方式,你可以使用自定义活页夹)。但是,这并不能保证与 C# 重载解析规则完全匹配,因为默认绑定器与语言无关。
  • @PavelMinaev 哇,很高兴知道。我相应地更新了代码示例。
【解决方案2】:

我的解决方案是:

  1. 解析您的原始输入(脚本)字符串
  2. Lex & Map(函数到函数,变量到字典)
  3. 执行。

如果您可以将指令解析为可标记的字符串,那么您可以基于这些“字符串”执行非常具体的功能。

我刚刚发布了一个video playlist,可能值得一试。

【讨论】:

    猜你喜欢
    • 2017-09-02
    • 1970-01-01
    • 1970-01-01
    • 2023-03-11
    • 2013-02-18
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多