接口作为接口返回类型

本文关键字:接口 返回类型 | 更新日期: 2023-09-27 17:50:35

在我的应用程序中,我使用不同的web api来获取汽车信息。对于服务,我实现了ICarService。由于所有这些Api返回的汽车数据集略有不同,我实现了ICar接口,因此每个服务可以返回自己的汽车类型,但在我的应用程序中,我可以使用"通用"ICar。

这是我的实现:

// Car Model
public interface ICar
{
    string Color { get; }
}
public class CarApiA : ICar
{
    public int car_color { get; set; }
    public Color
    {
        get { return this.car_color; }
    }
}

// Service
public interface ICarService
{
    Task<List<ICar>> GetCarsAsync(string search);
}
public class CarApiAService : ICarService
{
    public async Task<List<CarApiA>> GetCarsAsync(string search)
    {
        HttpClient client = new HttpClient();
        var response = await client.GetAsync(url);
        string content = await response.Content.ReadAsStringAsync();
        return  JsonConvert.DeserializeObject<List<CarApiA>>(content);
    }
}

现在我得到错误消息"'CarApiAService'不实现接口成员'ICarService.GetCarsAsync(string)'。'CarApiAService.GetCarsAsync(string)'不能实现'ICarService.GetCarsAsync(string)',因为它没有匹配的返回类型'System.Threading.Tasks.Task>'。"

如何使用接口返回接口?如果我的这种执行思路是完全错误的,请指导我正确的方向。

接口作为接口返回类型

考虑使用IEnumerable而不是IList。这允许您使用协变泛型类型:

public async Task<IEnumerable<ICar>> GetCarsAsync(string search)
{
    // ...
    return JsonConvert.DeserializeObject<List<CarApiA>>(content);
}

(当然接口也必须更新…)

public interface ICarService
{
    Task<IEnumerable<ICar>> GetCarsAsync(string search);
}

如果你想知道泛型类型的协方差,这里有一个解释:

  • 只有泛型接口可以协变(不是像List<T>这样的泛型具体类型)
  • 接口只能是协变的,如果泛型类型被定义为out(即只读)。这就是为什么IEnumerable<out T>是协变的而IList<T>不是

请参阅Jon Skeet的回答和Eric Lippert的博客。