如何用.NET反射Emit实现泛型接口及其实现类?
反射Emit实现泛型接口时的TypeLoadException问题解决
问题场景
尝试使用.NET反射Emit生成类并实现多个接口,其中包含泛型接口,调用class_builder.CreateType()时始终抛出异常,仅移除泛型接口实现代码才能正常运行。
期望等价的C#代码
public interface MyInterface1 { void IfaceMethod(int arg); } public interface MyInterface2<T> { void IfaceMethod(int arg); } public interface MyInterface3<T> { void IfaceMethod(T arg); } public class MyClass : MyInterface1, MyInterface2<double>, MyInterface3<int> { void MyInterface1.IfaceMethod(int arg) { Console.WriteLine(...); } void MyInterface2<double>.IfaceMethod(int arg) { Console.WriteLine(...); } void MyInterface3<int>.IfaceMethod(int arg) { Console.WriteLine(...); } }
原始反射Emit实现代码
using System.Reflection; using System.Reflection.Emit; class Test { static void Main() { string example_name = "Interface example"; AssemblyName asm_name = new AssemblyName(example_name); AssemblyBuilder asm_builder = AssemblyBuilder.DefineDynamicAssembly(asm_name, AssemblyBuilderAccess.Run); ModuleBuilder module_builder = asm_builder.DefineDynamicModule(example_name); TypeBuilder class_builder = module_builder.DefineType("MyClass", TypeAttributes.Public | TypeAttributes.Class); TypeBuilder interface1_builder = module_builder.DefineType("MyInterface1", TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract); TypeBuilder interface2_builder = module_builder.DefineType("MyInterface2", TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract); TypeBuilder interface3_builder = module_builder.DefineType("MyInterface3", TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract); Type[] interface2_generics = interface2_builder.DefineGenericParameters(["T"]); Type[] interface3_generics = interface3_builder.DefineGenericParameters(["T"]); MethodAttributes method_attributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Abstract; interface1_builder.DefineMethod("IfaceMethod", method_attributes, null, [typeof(int)]); interface2_builder.DefineMethod("IfaceMethod", method_attributes, null, [typeof(int)]); interface3_builder.DefineMethod("IfaceMethod", method_attributes, null, interface3_generics); Type interface1_type = interface1_builder.CreateType(); Type interface2_type = interface2_builder.CreateType(); Type interface3_type = interface3_builder.CreateType(); /* 让MyClass实现MyInterface1、MyInterface2<double>和MyInterface3<int>的IfaceMethod */ List<Type> interfaces = new List<Type>(); // Interface1始终正常工作 interfaces.Add(interface1_type); // 添加Interface2会报错:未处理的异常。System.TypeLoadException: 程序集'Interface example, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'中的类型'MyClass'尝试重写方法'fn_0',但未实现或继承该方法。 interfaces.Add(interface2_type.MakeGenericType([typeof(double)])); // 添加Interface3会报错:未处理的异常。System.TypeLoadException: 方法实现的主体签名与声明不匹配。类型: 'MyClass'。程序集: 'Interface example, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'。 interfaces.Add(interface3_type.MakeGenericType([typeof(int)])); List<MethodInfo> methods = new List<MethodInfo>(); for(int i = 0; i < interfaces.Count; i++){ Type interface_type = interfaces[i]; class_builder.AddInterfaceImplementation(interface_type); string method_name = "fn_"+i; MethodBuilder class_method = class_builder.DefineMethod(method_name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, null, [typeof(int)]); ILGenerator il = class_method.GetILGenerator(); il.EmitWriteLine("Hello from " + method_name + " implementing IfaceMethod from " + interface_type.Name); il.Emit(OpCodes.Ret); MethodInfo interface_method = interface_type.GetMethod("IfaceMethod"); class_builder.DefineMethodOverride(class_method, interface_method); methods.Add(interface_method); } Type class_type = class_builder.CreateType(); object obj = Activator.CreateInstance(class_type); Object[] args = [123]; foreach(MethodInfo method in methods){ method.Invoke(obj, args); } } }
错误信息
- 添加
MyInterface2<double>时抛出:
未处理的异常:System.TypeLoadException: 程序集'Interface example, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'中的类型'MyClass'尝试重写方法'fn_0',但未实现或继承该方法。 at System.Reflection.Emit.RuntimeTypeBuilder.CreateTypeNoLock() at System.Reflection.Emit.RuntimeTypeBuilder.CreateTypeInfoImpl() at Test.Main() in C:\tmp\interface-issue\Program.cs:line 62
- 添加
MyInterface3<int>时抛出:
未处理的异常:System.TypeLoadException: 方法实现的主体签名与声明不匹配。类型: 'MyClass'。程序集: 'Interface example, Version=0.0.0.0, Culture=neutral, PublicKeyToken=null'。 at System.Reflection.Emit.RuntimeTypeBuilder.CreateTypeNoLock() at System.Reflection.Emit.RuntimeTypeBuilder.CreateTypeInfoImpl() at Test.Main() in C:\tmp\interface-issue\Program.cs:line 62
修正后的代码
using System; using System.Reflection; using System.Reflection.Emit; using System.Collections.Generic; using System.Linq; class Test { static void Main() { string example_name = "Interface example"; AssemblyName asm_name = new AssemblyName(example_name); AssemblyBuilder asm_builder = AssemblyBuilder.DefineDynamicAssembly(asm_name, AssemblyBuilderAccess.Run); ModuleBuilder module_builder = asm_builder.DefineDynamicModule(example_name); TypeBuilder class_builder = module_builder.DefineType("MyClass", TypeAttributes.Public | TypeAttributes.Class); TypeBuilder interface1_builder = module_builder.DefineType("MyInterface1", TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract); TypeBuilder interface2_builder = module_builder.DefineType("MyInterface2", TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract); TypeBuilder interface3_builder = module_builder.DefineType("MyInterface3", TypeAttributes.Public | TypeAttributes.Interface | TypeAttributes.Abstract); Type[] interface2_generics = interface2_builder.DefineGenericParameters(["T"]); Type[] interface3_generics = interface3_builder.DefineGenericParameters(["T"]); MethodAttributes method_attributes = MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Abstract; List<MethodBuilder> interface_method_builders = new List<MethodBuilder>(); interface_method_builders.Add(interface1_builder.DefineMethod("IfaceMethod", method_attributes, null, [typeof(int)])); interface_method_builders.Add(interface2_builder.DefineMethod("IfaceMethod", method_attributes, null, [typeof(int)])); interface_method_builders.Add(interface3_builder.DefineMethod("IfaceMethod", method_attributes, null, interface3_generics)); interface1_builder.CreateType(); interface2_builder.CreateType(); interface3_builder.CreateType(); List<Type> interfaces = new List<Type>(); interfaces.Add(interface1_builder); interfaces.Add(interface2_builder.MakeGenericType([typeof(double)])); interfaces.Add(interface3_builder.MakeGenericType([typeof(int)])); for(int i = 0; i < interfaces.Count; i++){ Type interface_type = interfaces[i]; MethodInfo interface_method = interface_method_builders[i]; try { // 如果是泛型接口,获取实例化后的方法引用 interface_method = TypeBuilder.GetMethod(interface_type, interface_method); } catch(Exception) { } class_builder.AddInterfaceImplementation(interface_type); string method_name = "fn_"+i; MethodBuilder class_method = class_builder.DefineMethod(method_name, MethodAttributes.Public | MethodAttributes.Virtual | MethodAttributes.Final, null, [typeof(int)]); ILGenerator il = class_method.GetILGenerator(); il.EmitWriteLine("Hello from " + method_name + " implementing IfaceMethod from " + interface_type.Name); il.Emit(OpCodes.Ret); class_builder.DefineMethodOverride(class_method, interface_method); } Type class_type = class_builder.CreateType(); object obj = Activator.CreateInstance(class_type); List<MethodInfo> methods = class_type.GetInterfaces().Select(i => i.GetMethod("IfaceMethod")).ToList(); Object[] args = [123]; foreach(MethodInfo method in methods){ method.Invoke(obj, args); } } }
关键修正点
- 保存接口方法的
MethodBuilder引用,而非创建接口类型后通过GetMethod获取,避免泛型方法签名匹配偏差 - 使用
TypeBuilder.GetMethod获取泛型实例化后的接口方法,确保方法元数据与泛型实例化后的签名完全匹配
内容的提问来源于stack exchange,提问作者pmikkelsen
相关产品推荐
相关产品推荐

