2013-01-11 116 views
5

我的C#技能低,但我不明白爲什麼以下故障:C#泛型和接口和簡單OO

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#知識。

回答

12

你不能從一個List<Order>轉換到IList<IQuotable>。它們不兼容。畢竟,您可以將任意種類的IQuotable添加到IList<IQuotable>--但您只能將Order(或子類型)添加到List<Order>

三個選項:

  • 如果你使用.NET 4.0或更高版本,如果你改變你的代理方法,你可以使用協方差:如果你只

    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()); 
    
+0

謝謝!我的思想總是List是IList的具體實現。順序是相同的(但是當然可以有更多的IQuotables,所以只要他們用IQuotable實現IList就可以傳遞任何東西,顯然情況並非如此,所以我必須閱讀協變性。 net 2,因爲這是一個CLR存儲過程,只能使用.net 2。最後,我使用了你的第二個例子,我認爲它是有意義的,並完成我所需要的。 – Daniil

9

IList不是協變的。你不能投List<Order>IList<Quotable>

可以更改GetQuotes到簽名:

public void GetQuotes(IEnumerable<IQuotable> quotes) 

然後,兌現列表(如果你需要它的功能),通過:

var list = quotes.ToList();