C#发出对泛型方法的调用

Tho*_*kow 3 c# generics cil reflection.emit

上课了

class C
{
    public T Get<T>()
    {
        return default;
    }

    public void M()
    {
        int i = this.Get<Int32>();
    }
}
Run Code Online (Sandbox Code Playgroud)

我要生成的身体M在运行时使用Reflection.Emit,并ILGenerator使其恰好类似于什么是如上图所示.


我尝试的是

ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Call, typeof(C).GetMethod(nameof(C.Get), BindingFlags.Instance));
Run Code Online (Sandbox Code Playgroud)

产量

ldarg.0
call instance !!0 C::Get<M0>(string)
//                       ^^
ret
Run Code Online (Sandbox Code Playgroud)

但我需要得到

ldarg.0
call instance !!0 C::Get<int32>(string)
//                       ^^^^^
ret
Run Code Online (Sandbox Code Playgroud)

(注意调用中的不同类型参数C.Get<T>)


当发出对通用cfunction的调用时,如何传递泛型参数的类型(即取消M0int32反过来说)?

Lua*_*aan 8

您需要使用MakeGenericMethod替换类型参数:

ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit
( 
  OpCodes.Call, 
  typeof(C)
  .GetMethod(nameof(C.Get), BindingFlags.Instance)
  .MakeGenericMethod(typeof(int))
);
Run Code Online (Sandbox Code Playgroud)