1

我正在使用 Reflection.Emit 来构建一个数学表达式解析器(例如2+2)。一个类接收一个中缀表达式(例如2+2),将其转换为一个后缀表达式(例如2 2 +),然后另一个类将该后缀表达式编译为 IL 并创建一个DynamicMethod. 从那里,可以像在编译时以相似的速度创建表达式一样评估表达式。

这个编译器还支持隐式乘法,所以像这样x(2 + 2)计算为x * (2 + 2)

现在,我正在尝试实现用户定义的函数(例如f(x))。当我试图区分隐式乘法(如上所示)和用户定义的函数时,就会出现问题。这方面的一个例子是,如果用户输入x(5),我如何知道他们是要乘以x5还是x使用参数调用函数5

为了解决这个问题,在前一种情况下,编译器将一条if语句插入到 IL 流中。它调用一个函数来确定该函数是否使用标识符定义x。如果有,则MethodInfo通过out变量和局部变量将实例插入堆栈。

我的实际问题是,是否可以使用堆栈上的实例执行与编译期间MethodInfo调用速度相当的方法?IlGenerator.Emit(OpCodes.Call, MethodInfo)

谢谢。

4

1 回答 1

1

我知道允许您调用MethodInfo堆栈上的实例的唯一方法是调用其上的Invoke方法。我相信您已经意识到这种可能性,但您担心它可能太慢了。我建议您尝试一下并在压力下计时。您可能会发现它对于您的目的来说已经足够快了。

如果不是,那么您将不得不考虑如何重组您的设计,以免传递MethodInfo实例。例如,您可以改为传递托管函数指针。这些是ldftnldvirtftn指令返回的东西。然后,您可以使用该calli指令来调用其中之一。您将需要使用calli构建“调用站点描述”,它期望作为操作数。SignatureHelper

于 2010-08-20T04:00:41.577 回答