获取已关闭的未创建泛型方法的令牌
本文关键字:创建 泛型方法 令牌 获取 | 更新日期: 2023-09-27 18:34:40
我正在使用MethodBuilder.SetMethodBody()
来发出该方法,而不是使用内置的ILGenerator
。原因主要是对异常处理信息进行更多控制,并且通常对发出的操作码有更多的控制。
在我需要对我正在调用的方法发出调用的所有情况下ModuleBuilder.GetMethodToken()
它工作正常,除非我需要call
未创建的封闭泛型方法(具有相同的动态模块(。它抛出了一个NotSupportedException:Specified method is not supported.
.
当然MethodBuilder.TokenMetadata
不起作用,因为该方法是未创建的,这使我无所事
所以问题是,如何让令牌用于向此泛型方法自定义发射call
操作码?
编辑:我发现内置ILGenerator.EmitCall
通过调用接受布尔值的内部方法来获取令牌,生成器有时会传递 false。但是,MethodBuilder.GetMethodToken()
始终传递给相同的内部方法。好像是这样,但既然内部方法超出了我的能力范围,那么还得有另一种方法吗?
如果没有其他方法,我实际上正在考虑使用反射来手动获取和调用该方法。
编辑:事实上,通过反射调用内部方法(顺便说一句,ModuleBuilder.GetMethodTokenInternal
顺便说一下(以 false 作为参数确实解决了这个问题。但我不相信没有正常的方式来获取令牌,因为如果您手动调用泛型方法,SetMethodBody
需要它。
我想出的解决方案是通过反射调用内部方法并向其传递所需的参数。
// If the to be called method is generic...
var methodInfo = Type.GetType("System.Reflection.Emit.ModuleBuilder")
.GetTypeInfo()
.DeclaredMethods
.Where((method) => method.Name == "GetMethodTokenInternal" && method.GetParameters().Length == 3)
.First();
int token =
(int)methodInfo.Invoke(_moduleBuilder, new object[] { closedGenericMethod, null, false });
但我实际上使用委托在第一次调用后使事情变得更快。