如何解决使用泛型和接口时的 "No implicit reference conversion" 问题

How to resolve a "No implicit reference conversion" issue when using Generics & Interfaces

有什么想法可以修复以下错误或重构我的方法来避免它吗?

我定义了以下接口:

public interface IApiClient<TConfig, TOrder>
    where TConfig : IApiClientConfiguration
    where TOrder : IApiClientOrder
{
    TConfig Configuration { get; }

    IApiClientOrderConverter<TOrder> GetOrderConverter();

    Task<IEnumerable<TOrder>> GetNewOrdersAsync();
}

public interface IApiClientOrderConverter<TOrder>
    where TOrder : IApiClientOrder
{
    WarehouseOrder ClientOrderToWarehouseOrder(TOrder order);
}

基于它的实现:

public class SolidApiClient : IApiClient<SolidApiClientConfiguration, SolidOrder>
{
    public SolidApiClientConfiguration Configuration { get; }
    
    public IApiClientOrderConverter<SolidOrder> GetOrderConverter()
    {
        ...
    }
    
    public async Task<IEnumerable<SolidOrder>> GetNewOrdersAsync()
    {
        ...
    }
}

我正在尝试使用以下签名调用一个函数:

protected async Task ProcessClients<T>(IEnumerable<IApiClientConfiguration> clientConfigs)
    where T : IApiClient<IApiClientConfiguration, IApiClientOrder>
{
    ...
}

我正试图这样称呼它:

await ProcessClients<SolidApiClient>(clientsConfig);

但由于以下错误,我无法使用 SolidApiClient 进行通用调用:

错误 CS0311 类型 'SolidApiClient' 不能用作泛型类型或方法 'Function.ProcessClients(string, IEnumerable)' 中的类型参数 'T'。没有从 'SolidApiClient' 到 'IApiClient<IApiClientConfiguration, IApiClientOrder>'.

的隐式引用转换

我看到这里发布了很多不同的问题,它们很相似,但我还没有设法从到目前为止找到的答案中找到解决方案,所以我会伸出援手,以防有人发现我的方法有问题我错过了。

我也尝试了我的方法的一些变体,但似乎只是将问题转移到代码的不同部分,所以相信我一定是在接口 类 和泛型上使用了有缺陷的方法.

根据@pinkfloydx33 的建议,我改变了使用抽象基础 类 的方法。

作为奖励,摆脱接口和泛型极大地简化了解决方案。在我的特定场景中,使用接口和泛型是一个糟糕的选择。

要使用 ProcessClients,需要定义与 IApiClient<...>;

相同的通用约束
ProcessClients<TClient, TConfig, TOrder>
    (IEnumerable<TConfig> clientConfigs)
    where TClient : IApiClient<TConfig, TOrder>
    where TConfig : IApiClientConfiguration
    where TOrder : IApiClientOrder

这感觉就像代码的味道。另一种隐藏这种复杂性的方法是定义更多的接口,这样就不需要一直引用通用接口;

    interface IApiClient {}
    interface IApiClient<T> : IApiClient {}