C#发出对通用方法的调用

时间:2018-11-21 07:46:03

标签: c# generics cil reflection.emit

上课

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

    public void M()
    {
        int i = this.Get<Int32>();
    }
}

我想在运行时使用MReflection.Emit生成ILGenerator的正文,以使其完全类似于上面显示的内容。


我尝试过的是

ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit(OpCodes.Call, typeof(C).GetMethod(nameof(C.Get), BindingFlags.Instance));

产生

ldarg.0
call instance !!0 C::Get<M0>(string)
//                       ^^
ret

但是我需要得到

ldarg.0
call instance !!0 C::Get<int32>(string)
//                       ^^^^^
ret

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


发出对通用函数的调用时,如何传递通用参数的类型(即摆脱M0并改为使用int32)?

1 个答案:

答案 0 :(得分:8)

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

ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit
( 
  OpCodes.Call, 
  typeof(C)
  .GetMethod(nameof(C.Get), BindingFlags.Instance)
  .MakeGenericMethod(typeof(int))
);