2012-07-06 27 views
8

Tôi đã đơn giản hóa và sao chép vấn đề của mình trong mã bên dưới. Lỗi mà tôi nhận được là: Đối số 1: không thể chuyển đổi từ 'System.Collections.ObjectModel.Collection' thành 'System.Collections.ObjectModel.CollectionC# Truyền tập hợp dưới dạng tập hợp các giao diện

Một số nền tảng cho các quyết định thiết kế dẫn đến vấn đề này: Tôi có đã tạo ra một dịch vụ web để xử lý "IFruit", nhưng do bản chất của SOAP và các ràng buộc điểm cuối khi tôi hiểu chúng tôi đã tạo ra các phương pháp với việc thực hiện rõ ràng NẾU. Trên lớp nghiệp vụ, việc tạo một phương pháp riêng biệt cho mỗi lần triển khai trái cây cụ thể trước hết sẽ gây ra nhiều mã trùng lặp và thứ hai là lớp kinh doanh và dịch vụ đủ chặt chẽ chấp nhận các loại NẾU mới trong dịch vụ web sau này cũng sẽ yêu cầu thay đổi mã của tôi trong lớp nghiệp vụ (thêm một bản sao của mã dự phòng). Thiết kế này là một trong những tôi đã thực hiện thành công bằng cách sử dụng Java trong quá khứ, nhưng giao diện C# dường như chỉ là đủ khác nhau để ném tôi. Xin cho biết.

public interface IFruit{ 
    public string TakeBite(); 
} 

public Apple : IFruit{ 
    public string TakeBite(){ 
     return "tasty bite of apple"; 
    } 
} 

public void EatFruit(Collection<IFruit> fruits){ 
    foreach(var fruit in fruits){ 
     Console.WriteLine(fruit.TakeBite()); 
    } 
} 

public void EatApples(Collection<Apple> apples){ 
    this.EatFruit(apples); 
} 

Trả lời

9

Hãy thử thay đổi phương pháp EatFruit bạn để chấp nhận IEnumerable<IFruit>

public void EatFruit(IEnumerable<IFruit> fruits) 
{ 
    foreach (var fruit in fruits) 
    { 
     Console.WriteLine(fruit.TakeBite()); 
    } 
} 

Giao diện IEnumerable<out T> hỗ trợ hiệp phương sai vì nó được đánh dấu bằng các modifier out. Collection<T> không được đánh dấu bằng công cụ sửa đổi.

+0

Cảm ơn bạn. Điều này biên dịch.Bây giờ để cập nhật các bài kiểm tra đơn vị của tôi. – YouGotCSharpInMyJava

1

Gọi là hiệp phương sai.
Tuy nhiên, không thể thực hiện với các bộ sưu tập có thể thay đổi.

Nếu không, có thể viết EatFruit

fruits.Add(new Orange()); 

Net 4 không hỗ trợ hiệp phương sai cho các giao diện reas chỉ, vì vậy bạn có thể thay đổi nó để IEnumerable<IFruit> và nó sẽ làm việc.

+0

Giả sử thực hiện cam Nếu có thì có vấn đề gì? – Charleh

+1

@Charleh: 'fruits' là _actually_ a' Bộ sưu tập '. Nó không thể giữ một 'màu da cam'. – SLaks

+0

Tôi nghĩ từ trái cây là một bộ sưu tập rằng nó có thể chứa bất kỳ loại thực hiện IFruit? – Charleh

0

Bên cạnh sử dụng IEnumerable bạn có thể gõ kiểm tra bộ sưu tập (bit khủng nhưng nó phải làm việc):

public void EatApples(Collection<IFruit> fruit) 
    var col = new Collection<IFruit>(); 

    fruit.Where(x => x is Apple).ToList().ForEach(x => col.Add(x)); 

    this.EatFruit(col); 
} 

Mặc dù tôi muốn sử dụng IEnumerable thay vì - đây chỉ là một lựa chọn nếu bạn không thể cấu trúc lại: P

(đó là as type an toàn khi bạn thực hiện nó!)

+0

Điều đó sẽ làm việc 2x - tạo một Danh sách rồi thêm từng bộ sưu tập vào Bộ sưu tập. Tốt hơn để làm: 'foreach (var x trong fruit.OfType ()) {col.Add (x); } '. –

+0

Vâng đúng - không nơi nào tôi nói nó sẽ được performant (và tôi đã đề cập đến kinh khủng trong đó quá!): D – Charleh

0

giải pháp đơn giản:

public void EatApples(Collection<Apple> apples){ 
    this.EatFruit(
      new Collection<IFruit>(
       apples.Cast<IFruit>() 
     ) 
    ); 
} 

Giải pháp tốt hơn: sử dụng hiệp phương sai được giới thiệu trong C# 4: xem Câu trả lời của Kevin

Các vấn đề liên quan