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

如何用.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);
        }
    }
}

关键修正点

  1. 保存接口方法的MethodBuilder引用,而非创建接口类型后通过GetMethod获取,避免泛型方法签名匹配偏差
  2. 使用TypeBuilder.GetMethod获取泛型实例化后的接口方法,确保方法元数据与泛型实例化后的签名完全匹配

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.06.12 01:40:58