[英]Call a method using a MethodInfo instance on the stack using Reflection.Emit
我正在使用Reflection.Emit構建數學表達式解析器(例如2+2
)。 一個類接受一個后綴表達式(例如2+2
),將其轉換為后綴表達式(例如2 2 +
),然后另一個類將該后綴表達式編譯為IL並創建DynamicMethod
。 從那里,可以像在編譯時創建表達式一樣以類似的速度對其進行求值。
該編譯器還支持隱式乘法,因此類似x(2 + 2)
為x * (2 + 2)
現在,我正在嘗試實現用戶定義的函數(例如f(x)
)。 當我嘗試區分如上所示的隱式乘法和用戶定義的函數時,會出現問題。 例如,如果用戶輸入x(5)
,我如何知道他們是要將x
乘以5
還是使用參數5
調用x
函數?
為了解決這個問題,在前一種情況下,編譯器在IL流中插入一個if
語句。 它調用一個函數來確定該函數是否用x
的標識符定義。 如果存在,那么它將通過out
變量和局部變量將MethodInfo
實例插入堆棧。
我的實際問題是,是否有可能在堆棧上使用MethodInfo
實例執行與在編譯過程中調用IlGenerator.Emit(OpCodes.Call, MethodInfo)
速度等效的方法?
謝謝。
我知道的唯一允許您在堆棧上調用MethodInfo
實例的方法是在其上調用Invoke
方法。 我確定您已經意識到這種可能性,但是您擔心它可能太慢。 我建議您嘗試一下,並在壓力下調整性能。 您可能會發現它足夠快達到您的目的。
如果不是,那么您將不得不考慮如何重組設計,以免傳遞MethodInfo
實例。 例如,您可以改為傳遞托管函數指針。 這些就是ldftn
和ldvirtftn
指令返回的內容。 然后,您可以使用calli
指令來調用其中之一。 您將需要使用SignatureHelper
類構造“ call-site description”( calli
期望作為操作數)。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.