C# 发出对泛型方法的调用
C# emit call to generic method
拥有 class
class C
{
public T Get<T>()
{
return default;
}
public void M()
{
int i = this.Get<Int32>();
}
}
我想在运行时使用 Reflection.Emit
和 ILGenerator
生成 M
的正文,以便它与上面显示的完全相似。
我试过的是
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>
时的不同类型参数)
发出对通用 cfunction 的调用时,我如何传递通用参数的类型(即摆脱 M0
并让它说 int32
)?
您需要将类型参数替换为 MakeGenericMethod:
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit
(
OpCodes.Call,
typeof(C)
.GetMethod(nameof(C.Get), BindingFlags.Instance)
.MakeGenericMethod(typeof(int))
);
拥有 class
class C
{
public T Get<T>()
{
return default;
}
public void M()
{
int i = this.Get<Int32>();
}
}
我想在运行时使用 Reflection.Emit
和 ILGenerator
生成 M
的正文,以便它与上面显示的完全相似。
我试过的是
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>
时的不同类型参数)
发出对通用 cfunction 的调用时,我如何传递通用参数的类型(即摆脱 M0
并让它说 int32
)?
您需要将类型参数替换为 MakeGenericMethod:
ilGenerator.Emit(OpCodes.Ldarg_0);
ilGenerator.Emit
(
OpCodes.Call,
typeof(C)
.GetMethod(nameof(C.Get), BindingFlags.Instance)
.MakeGenericMethod(typeof(int))
);