代码之家  ›  专栏  ›  技术社区  ›  user153498

使用Reflection.Emit在堆栈上的MethodInfo实例调用方法

  •  1
  • user153498  · 技术社区  · 15 年前

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

    此编译器还支持隐式乘法,因此 x(2 + 2) 评估为 x * (2 + 2)

    现在,我正在尝试实现用户定义的函数(例如 f(x) )当我试图区分隐式乘法(如上所示)和用户定义函数时,会出现一个问题。例如,如果用户输入 x(5) ,我如何知道它们是否要乘法 x 通过 5 或调用 X 参数为的函数 ?

    为了解决这个问题,在前面的例子中,编译器插入 if 语句进入IL流。它调用一个函数来确定该函数是否使用的标识符 X . 如果有,则插入 MethodInfo 实例通过 out 变量和局部变量。

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

    谢谢。

    1 回复  |  直到 15 年前
        1
  •  1
  •   Timwi    15 年前

    我知道的唯一方法是让你调用 MethodInfo 堆栈上的实例是通过调用 Invoke 方法。我相信你已经意识到这种可能性,但你担心它可能太慢了。我建议你试试看,在压力下计时。你可能会发现它的速度足以满足你的目的。

    如果不是,那么你就得考虑如何重新设计你的设计,这样你就不会错过 方法信息 实例。例如,您可以传递托管函数指针。这些都是 ldftn ldvirtftn 指令返回。然后您可以使用 calli 调用其中一个的指令。您需要构建呼叫站点描述,其中 愈伤组织 应为操作数,使用 SignatureHelper class .