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

如何通过反射调用实现泛型接口的类中的方法

调用泛型接口实现类方法的延迟绑定异常问题

我希望调用当前程序集中实现特定泛型接口的对象方法,现有条件:

  • 泛型接口IMyContract<T>(T为类);
  • 两个模型类:MyContractModel和MyContractModel2;
  • 两个服务类:MyContractService实现IMyContract<MyContractModel>,MyContractService2实现IMyContract<MyContractModel2>;
  • 已通过services.AddSingleton将服务注册到依赖注入容器中。

目前能从程序集中获取正确的接口类型,并从依赖注入中加载服务实例,但调用方法时因编译器无法识别类型出现延迟绑定异常。请问该操作是否可行?若不可行,给出替代方案。

现有代码

// Register services
var serviceCollection = new ServiceCollection();
serviceCollection.AddSingleton<IMyContract<MyContractModel>, MyContractService>();
serviceCollection.AddSingleton<IMyContract<MyContractModel2>, MyContractService2>();
var serviceProvider = serviceCollection.BuildServiceProvider();

// Load all contract processors (that implement `IMyContract`) and invoke `Process` on them
var iContractPrcessor = typeof(IMyContract<>);

IEnumerable<Type> allTypesInThisAssembly = Assembly.GetExecutingAssembly().GetTypes();

foreach(Type type in allTypesInThisAssembly)
{
    if (type.GetInterface(iContractPrcessor.Name.ToString()) != null)
    {
        // As expected in 1st iteration, produces IMyContract<MyContractModel> 
        Type implementedInterface = type.GetInterface(iContractPrcessor.Name.ToString());

        // As expected in 1st iteration, produces MyContractService
        var contractService = serviceProvider.GetService(implementedInterface);

        MethodInfo method = iContractPrcessor.GetMethod("Process");

        //This throws an exception: late bound operation exception
        var result = (Task) method.Invoke(contractService, null);
        await result.ConfigureAwait(false);
    }
}

public interface IMyContract<T> where T : class
{
    Task Process();
}

public class MyContractModel
{
    public string Name { get; set; } = "";
}

public class MyContractService : IMyContract<MyContractModel>
{
    public Task Process()
    {
        Console.WriteLine("MyContractService Process");
        return Task.CompletedTask;
    }
}

public class MyContractModel2
{
    public string Name { get; set; } = "";
}

public class MyContractService2 : IMyContract<MyContractModel2>
{
    public Task Process()
    {
        Console.WriteLine("MyContractService2 Process");
        return Task.CompletedTask;
    }
}
解决方案

问题原因

直接从开放泛型类型IMyContract<>获取Process方法,再用它调用具体泛型实现类的实例会触发延迟绑定异常——开放泛型的方法与具体封闭泛型(如IMyContract<MyContractModel>)的方法并非同一个MethodInfo实例,无法跨类型调用。

可行方案

方案1:修正反射调用逻辑

循环中拿到具体的封闭泛型接口(implementedInterface)后,从该接口类型获取Process方法,而非从开放泛型类型获取:

foreach(Type type in allTypesInThisAssembly)
{
    // 仅处理具体服务类,排除接口、抽象类
    if (type.IsClass && !type.IsAbstract)
    {
        // 筛选出实现了IMyContract<>的封闭泛型接口
        var implementedInterfaces = type.GetInterfaces()
            .Where(i => i.IsGenericType && i.GetGenericTypeDefinition() == typeof(IMyContract<>));
        
        foreach(var implementedInterface in implementedInterfaces)
        {
            var contractService = serviceProvider.GetService(implementedInterface);
            if (contractService == null) continue;
            
            // 从具体封闭泛型接口获取方法
            MethodInfo method = implementedInterface.GetMethod("Process");
            if (method == null) continue;
            
            var result = (Task)method.Invoke(contractService, null);
            await result.ConfigureAwait(false);
        }
    }
}

方案2:引入非泛型基接口(更简洁优雅)

给泛型接口定义一个非泛型基接口,让所有泛型实现类自动继承该接口,从而避免反射,直接通过依赖注入获取实例并调用方法:

// 新增非泛型基接口
public interface IMyContract
{
    Task Process();
}

// 泛型接口继承非泛型基接口
public interface IMyContract<T> : IMyContract where T : class
{
    // 可在此添加泛型特有的方法,Process已在基接口定义
}

// 服务类无需修改,自动实现IMyContract接口
public class MyContractService : IMyContract<MyContractModel>
{
    public Task Process()
    {
        Console.WriteLine("MyContractService Process");
        return Task.CompletedTask;
    }
}

// 调用逻辑简化
var allContractServices = serviceProvider.GetServices<IMyContract>();
foreach(var service in allContractServices)
{
    await service.Process().ConfigureAwait(false);
}

该方案性能更优,代码可读性更强,完全规避了反射的复杂性。

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

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.08.13 05:35:29