You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

.NET 8下Reflection.Emit泛型接口方法重写报错的解决方法

问题:动态实现泛型接口时GetMethod抛出NotSupportedException

运行环境为.NET 8,代码库中已存在泛型接口IJoinable<T1, T2>,该接口声明方法T2 Join(T1 value)。lType、rType、joinedType均为运行时动态生成的TypeBuilder变量。原实现代码如下:

var joinType = typeof(IJoinable<,>).MakeGenericType(rType, joinedType);
lType.AddInterfaceImplementation(joinType);
var joinMethod = lType.DefineMethod("Join", MethodAttributes.Public | MethodAttributes.Virtual, joinedType, [rType]);
var gen = joinMethod.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Call, ctor);
gen.Emit(OpCodes.Ret);
lType.DefineMethodOverride(joinMethod, joinType.GetMethod("Join")!);

执行最后一行joinType.GetMethod("Join")时抛出NotSupportedException,原因是System.Reflection.Emit.TypeBuilderInstantiation.GetMethodImpl()方法仅抛出此异常,不支持直接调用。


解决方案

问题核心在于joinType是通过TypeBuilder生成的泛型实例类型(TypeBuilderInstantiation),直接调用其GetMethod方法不被支持。正确做法是先从原始泛型接口获取方法定义,再绑定到泛型实例类型上。

修改后的代码如下:

// 先获取原始泛型接口的方法定义
var interfaceMethodTemplate = typeof(IJoinable<,>).GetMethod("Join")!;
// 创建泛型接口实例
var joinType = typeof(IJoinable<,>).MakeGenericType(rType, joinedType);
lType.AddInterfaceImplementation(joinType);

// 定义类中的实现方法
var joinMethod = lType.DefineMethod(
    "Join", 
    MethodAttributes.Public | MethodAttributes.Virtual, 
    joinedType, 
    new[] { rType });

// 生成IL逻辑
var gen = joinMethod.GetILGenerator();
gen.Emit(OpCodes.Ldarg_0);
gen.Emit(OpCodes.Ldarg_1);
gen.Emit(OpCodes.Call, ctor);
gen.Emit(OpCodes.Ret);

// 将原始方法模板绑定到泛型实例,得到可用的接口方法引用
var targetInterfaceMethod = interfaceMethodTemplate.MakeGenericMethod(rType, joinedType);
// 完成方法重写绑定
lType.DefineMethodOverride(joinMethod, targetInterfaceMethod);

关键说明

  • 先从未实例化的泛型接口IJoinable<,>获取方法定义,这是一个通用的方法模板。
  • 通过MakeGenericMethod传入动态生成的rType和joinedType,得到对应泛型实例接口的有效MethodInfo对象,该对象可正常用于DefineMethodOverride方法。

内容的提问来源于stack exchange,提问作者Mason Wheeler

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.26 18:06:15