c#带表达式树的动态调用方法

时间:2015-02-13 17:19:37

标签: c# dynamic expression-trees

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

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

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

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

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

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

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

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

并且DLR会找出要调用的函数重载。

问题是,我怎样才能以编程方式实现这一目标?

到目前为止,我没有运气

Expression.Dynamic(..)

2 个答案:

答案 0 :(得分:2)

只要您知道类型,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);

答案 1 :(得分:0)

我对此的解决方法是:

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

如果您可以将指令解析为可标记化的字符串,则可以基于这些“字符串”执行非常特定的功能。

我刚刚发布了一个video playlist,可能值得为此目的进行检查。