【问题标题】:Interface as interface return type接口作为接口返回类型
【发布时间】:2014-03-17 17:19:03
【问题描述】:

在我的应用中,我使用不同的网络 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' does not implement interface member 'ICarService.GetCarsAsync(string)'. 'CarApiAService.GetCarsAsync(string)' cannot implement 'ICarService.GetCarsAsync(string)' 因为它没有'System.Threading.Tasks.Task>' 的匹配返回类型。”

如何使用接口返回接口?如果这是我的实现想法完全错误,请指导我正确的方向。

【问题讨论】:

  • 您的Task&lt;List&lt;CarApiA&gt;&gt;ICarService 接口中的合约不匹配。这就是问题所在。只需将其更改为Task&lt;list&lt;ICar&gt;&gt;。这将起作用,因为CarApiA ICar
  • 您是否尝试过在 CarApiAService 中将 GetCarsAsync 的返回类型更改为 Task> ?
  • 当您指定一个泛型 List 时,它必须只包含该类型的对象 - 不能使用子类。
  • @PugFugly - 您当然可以将子类型的实例放入通用列表中,但您不能将 List&lt;Subclass&gt; 分配给 List&lt;Base&gt;
  • 是的,对不起,我的意思是分配整个列表而不是添加单个元素。我的坏

标签: c# windows-phone-8 interface


【解决方案1】:

考虑使用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&lt;T&gt; 这样的泛型具体类型)
  • 只有当泛型类型定义为out(即只读)时,接口才能是协变的。这就是为什么 IEnumerable&lt;out T&gt; 是协变的,而 IList&lt;T&gt; 不是的原因

另请参阅 Jon Skeet 的回答 hereEric Lippert's blog

【讨论】:

  • 注意,如果您使用的是 .NET 4.5 并且需要协方差,但您还需要获取集合的 .Count,请查看 IReadOnlyCollection&lt;T&gt;
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2021-09-29
  • 2019-01-15
  • 1970-01-01
  • 2011-05-16
  • 2020-09-04
  • 2019-05-10
相关资源
最近更新 更多