2013-01-11 30 views
5

My C# kỹ năng này là thấp, nhưng tôi không thể hiểu tại sao thất bại sau:C Generics # và các giao diện và OO đơn giản

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

Sau đó, các mã như sau:

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

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

Am I chỉ đơn giản là làm điều gì đó sai và không nhìn thấy nó? Vì Order thực hiện báo giá, một danh sách thứ tự sẽ đi vào như IList của quoatables. Tôi có một cái gì đó như trong Java và nó hoạt động, vì vậy tôi khá chắc chắn của nó thiếu kiến ​​thức C#.

Trả lời

12

Bạn không thể chuyển đổi từ một List<Order> đến một IList<IQuotable>. Chúng không tương thích. Sau khi tất cả, bạn có thể thêm bất kỳ loại IQuotable nào vào IList<IQuotable> - nhưng bạn chỉ có thể thêm Order (hoặc loại phụ) vào List<Order>.

Ba lựa chọn:

  • Nếu bạn đang sử dụng .NET 4 hoặc cao hơn, bạn có thể sử dụng hiệp phương sai nếu bạn thay đổi phương pháp proxy của bạn để:

    public void GetQuotes(IEnumerable<IQuotable> list) 
    

    việc chỉ này nếu bạn chỉ cần phải lặp qua danh sách, tất nhiên.

  • Bạn có thể làm GetQuotes chung với một hạn chế:

    public void GetQuotes<T>(IList<T> list) where T : IQuotable 
    
  • Bạn có thể xây dựng một List<IQuotable> để bắt đầu với:

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

Cảm ơn bạn! Suy nghĩ của tôi luôn là Danh sách là việc thực hiện cụ thể IList. Thứ tự là như nhau (nhưng có thể có nhiều IQuotables tất nhiên. Vì vậy, tôi có thể vượt qua bất cứ điều gì vào phương pháp miễn là họ thực hiện IList với IQuotable. Rõ ràng đó không phải là trường hợp vì vậy tôi phải đọc lên hiệp phương sai. net 2 vì đây là một thủ tục lưu trữ CLR mà chỉ mất .net 2. Cuối cùng, tôi đã sử dụng ví dụ thứ 2 của bạn mà, tôi nghĩ, có ý nghĩa và làm những gì chính xác những gì tôi cần. – Daniil

9

IList không phải là biến thể. Bạn không thể bỏ một số List<Order> đến số IList<Quotable>.

Bạn có thể thay đổi chữ ký của GetQuotes tới:

public void GetQuotes(IEnumerable<IQuotable> quotes) 

Sau đó, hiện thực một danh sách (nếu bạn cần các tính năng của nó), thông qua:

var list = quotes.ToList(); 
Các vấn đề liên quan