C#泛型和接口以及简单的OO

时间:2013-01-11 16:53:08

标签: c# oop generics

我的C#技能很低,但我无法理解为什么以下失败:

public interface IQuotable {}
public class Order : IQuotable {}
public class Proxy {
  public void GetQuotes(IList<IQuotable> list) { ... }
}

然后代码如下:

List<Order> orders = new List<Orders>();
orders.Add(new Order());
orders.Add(new Order());

Proxy proxy = new Proxy();
proxy.GetQuotes(orders); // produces compile error

我只是做错了什么而没有看到它?由于Order实现了Quotable,因此订单列表将作为可分配的IList。我有类似Java的东西,但是它很有用,所以我很确定它缺乏C#知识。

2 个答案:

答案 0 :(得分:12)

您无法从List<Order>转换为IList<IQuotable>。他们只是不兼容。毕竟,您可以将{em>任何类IQuotable添加到IList<IQuotable> - 但您只能向Order添加List<Order>(或子类型) }。

三个选项:

  • 如果您使用的是.NET 4或更高版本,则可以在将代理方法更改为:

    时使用协方差
    public void GetQuotes(IEnumerable<IQuotable> list)
    

    当你只需要遍历列表时,这只能起作用。

  • 您可以通过约束使GetQuotes通用:

    public void GetQuotes<T>(IList<T> list) where T : IQuotable
    
  • 您可以构建一个List<IQuotable>来开始:

    List<IQuotable> orders = new List<IQuotable>();
    orders.Add(new Order());
    orders.Add(new Order());
    

答案 1 :(得分:9)

IList不是协变的。您无法将List<Order>投射到IList<Quotable>

您可以将GetQuotes的签名更改为:

public void GetQuotes(IEnumerable<IQuotable> quotes)

然后,通过以下方式实现列表(如果需要其功能):

var list = quotes.ToList();