如何解决使用泛型和接口时的 "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 {}
有什么想法可以修复以下错误或重构我的方法来避免它吗?
我定义了以下接口:
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 {}