简体   繁体   English

接口作为接口返回类型

[英]Interface as interface return type

In my app I use different web api's for fetching car information. 在我的应用程序中,我使用不同的web api来获取汽车信息。 For the services I have implemented ICarService. 对于我已经实现了ICarService的服务。 As all of these Api's return little different set of car data, I have implemented ICar interface, so each services can return their own type of car but in my app I can use "general" ICar. 由于所有这些Api都返回了不同的汽车数据集,我已经实现了ICar接口,因此每个服务都可以返回自己的汽车类型,但在我的应用程序中我可以使用“通用”ICar。

Here is my implementation: 这是我的实现:

// 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);
    }
}

Now I get the error message "'CarApiAService' does not implement interface member 'ICarService.GetCarsAsync(string)'. 'CarApiAService.GetCarsAsync(string)' cannot implement 'ICarService.GetCarsAsync(string)' because it does not have the matching return type of 'System.Threading.Tasks.Task>'." 现在我收到错误消息“'CarApiAService'没有实现接口成员'ICarService.GetCarsAsync(string)'。'CarApiAService.GetCarsAsync(string)'无法实现'ICarService.GetCarsAsync(string)',因为它没有匹配的返回'System.Threading.Tasks.Task>'的类型。“

How I use interface to return interface? 我如何使用界面返回界面? If this my idea of implementation is completely wrong, please guide me to correct direction. 如果我的实施想法完全错误,请指导我正确指导。

Consider using IEnumerable instead of IList . 考虑使用IEnumerable而不是IList This allows you to use a covariant generic type: 这允许您使用协变泛型类型:

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

(Of course the interface also has to be updated…) (当然界面也必须更新......)

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

A word of explanation in case you were wondering about covariance with generic types: 如果您想知道与泛型类型的协方差,请解释一下:

  • only a generic interface can be covariant (not generic concrete types like List<T> ) 只有通用接口才能协变(不像List<T>这样的通用接口)
  • the interface can only be covariant if the generic type is defined as out (ie, read-only). 如果泛型类型被定义为out (即只读),则接口只能是协变的。 That's why IEnumerable<out T> is covariant but IList<T> is not 这就是为什么IEnumerable<out T>是协变的,但IList<T>不是

See also Jon Skeet's answer here , and Eric Lippert's blog . 又见乔恩斯基特的答案在这里 ,和埃里克利珀的博客

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM