Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/324.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181

Warning: file_get_contents(/data/phpspider/zhask/data//catemap/8/perl/11.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
带有表达式树的c#动态调用方法_C#_Dynamic_Expression Trees - Fatal编程技术网

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

带有表达式树的c#动态调用方法,c#,dynamic,expression-trees,C#,Dynamic,Expression Trees,我正在编写一个小型表达式解析器,并希望包含方法调用。 语法类似于:functionName('stringValue',intValue) 然后,表达式解析器应该使用正确的签名(在本例中为字符串int)查找名为“functionName”的静态函数 解析表达式没有问题,但调用right方法时遇到问题 到目前为止,我想到的是一个简单的表达式。调用: Expression.Call(typeof(MyContext).GetMethod(functionName), parameterExpress

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

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

解析表达式没有问题,但调用right方法时遇到问题

到目前为止,我想到的是一个简单的表达式。调用:

Expression.Call(typeof(MyContext).GetMethod(functionName), parameterExpressions)
这可以灵活地工作,并且可以在以后编译成一个可调用的函数。 但当许多不同的重载、默认参数、params关键字等发挥作用时,它变得很棘手。我不想重新实现重载解析的整个C#逻辑,并认为DLR可以帮助我

使用dynamic关键字,我可以写:

dynamic myC = MyContext;
return myC.functionName(param1, param2);
DLR将决定调用哪个函数重载

问题是,我如何通过编程实现这一点

到目前为止,我和你的关系还不太好

Expression.Dynamic(..)

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);

我的解决办法是:

  • 解析原始输入(脚本)字符串
  • Lex&Map(函数到函数,变量到字典)
  • 执行
  • 如果可以将指令解析为可标记的字符串,那么就可以基于这些“字符串”执行非常特定的功能


    为此,我刚刚发布了一个可能值得查看的版本。

    您知道参数的类型吗?我知道参数的类型(在运行时),所以这听起来很有希望!明天我会试试看,我只是在看GetMethods重载,而不是GetMethod!Thx对于您的帮助在仔细查看时,这将仅处理重载,但在存在例如默认参数的情况下不提供重载解析。采用类型数组的
    Expression.Call的重载不会对被调用的方法进行重载解析-该数组严格用于指定泛型类型参数,如果方法是泛型的。如果要执行重载解析,必须通过
    GetMethod
    (如果要自定义其工作方式,可以使用自定义活页夹)。但是,这并不保证与C#重载解析规则完全匹配,因为默认绑定器是语言不可知的。@PavelMinaev哦,哇,很高兴知道。我相应地更新了代码示例。