编程语言
首页 > 编程语言> > c# – 获取已关闭的未创建泛型方法的标记

c# – 获取已关闭的未创建泛型方法的标记

作者:互联网

我正在使用MethodBuilder.SetMethodBody()来发出方法,而不是使用内置的ILGenerator.原因主要是对异常处理信息进行更多控制,并且通常对发出的操作码有更多控制.

在我需要调用方法的所有情况下,我正在调用ModuleBuilder.GetMethodToken()并且它工作正常,除非我需要调用一个未创建的封闭泛型方法(使用相同的动态模块).它抛出NotSupportedException:不支持指定的方法..

当然,MethodBuilder.TokenMetadata不起作用,因为该方法是未创建的,这让我没有别的尝试.

所以问题是,如何在我的自定义发出调用操作码到这个通用方法时使用令牌?

编辑:我发现内置的ILGenerator.EmitCall通过调用接受bool的内部方法获取令牌,生成器有时会传递false.但是,MethodBuilder.GetMethodToken()始终将true传递给相同的内部方法.它似乎是这样,但由于内部方法是我无法实现的,还有另一种方法吗?

我实际上正在考虑使用反射来手动获取和调用该方法,如果没有别的办法的话.

编辑:的确,调用内部方法(这是ModuleBuilder.GetMethodTokenInternal顺便说一句)通过反射与false作为参数确实解决了问题.但我不相信没有正常的获取令牌的方法,因为如果您手动调用泛型方法,SetMethodBody需要它.

解决方法:

我想出的解决方案是通过反射调用内部方法并将其传递给所需的args.

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

但实际上我在第一次通话后使用委托来加快速度.

标签:c,net,reflection-emit
来源: https://codeday.me/bug/20190708/1402502.html