2010-01-28 34 views
5

Giả sử bạn có các lớp sau:Đi qua một bộ sưu tập giao diện

class Car : IPainting 
{ 
... 
} 

Sau đó, một chức năng như thế này:

void AddCars(IEnumerable<Car> collection) 

Sau đó, một đoạn mã như thế này:

Car bmw = new Car(); 
Car mercedes = new Car(); 

IPainting a = (IPainting) bmw; 
IPainting b = (IPainting) mercedes; 

IPainting[] paintings = new IPainting[] {a, b}; 

AddCars(paintings); // fails to compile 

này khóa học không biên dịch vì phương thức AddCars() chỉ chấp nhận một bộ sưu tập Ô tô nhưng đó là những gì mà mảng 'tranh' được tạo ra.

Tôi biết rằng C# 4.0 có thể sẽ cung cấp giải pháp cho việc này. Hôm nay có cách giải quyết nào không?

Cảm ơn,

Alberto

+1

C# 4.0 sẽ không cung cấp một giải pháp cho mã mà bạn có ở đây.Bạn sẽ không bao giờ có thể vượt qua một cái gì đó một loại đó là cao hơn trong hie thừa kế rarchy để một phương pháp mong đợi một cái gì đó thấp hơn. Như những người khác đã chỉ ra, phương pháp của bạn sẽ cần phải thực hiện trong IPainting - không xe cho điều này để làm việc. –

Trả lời

3

C# 4 sẽ không cho phép mã mà bạn đã viết, vì phương pháp này AddCars hy vọng một IEnumerable<Car> mà thực hiện IPainting. Điều này không có nghĩa là bạn có thể vượt qua mọi hoạt động lớp thực hiện IPainting (ví dụ: bạn có thể có class Bike : IPainting không có gì để làm với lớp học Car. Tuy nhiên, nó sẽ cho phép một cách khác, nếu bạn có void AddCars(IEnumerable<IPainting> collection) bạn có thể vượt qua một List<Car> đến phương pháp này.

cho đến lúc đó, bạn sẽ cần phải dính vào đi Car chuỗi để phương pháp này, bằng cách sử dụng một số cơ chế đúc (như painting.Cast<Car>() gợi ý trong câu trả lời khác).

+0

Là các bức tranh.Cộng số () một cách nào đó nhanh hơn một vòng lặp cho phép đưa từng đối tượng vào loại Ô tô? Cảm ơn. – abenci

+0

@devdept: Không thể nói; không bao giờ thực hiện bất kỳ so sánh hiệu suất nào về điều đó. Sẽ ngạc nhiên nếu nó không đủ nhanh cho hầu hết các kịch bản thế giới thực mặc dù. –

4

Làm thế nào về việc sử dụng LINQ: AddCars(paintings.Cast<Car>());

+0

Chúng tôi không sử dụng LINQ. Chúng tôi không sử dụng cơ sở dữ liệu nào cả. Tôi có thể đọc thêm về cách tiếp cận bạn đề xuất ở đâu? – abenci

+3

@devdept - đó là LINQ đối tượng, không phải LINQ to sql. Nó có _nothing_ để làm với cơ sở dữ liệu. –

7

Hãy thử sử dụng một phương pháp chung:

void AddCars<T>(IEnumerable<T> collection) where T : IPainting 
+0

Giải pháp này cho phép cả mảng Car [] và IPainting [] được truyền vào AddCars()? – abenci

+0

có, nó sẽ cho phép điều đó. –

4

Mã của bạn về cơ bản là sai lầm. Lớp học của bạn đảm bảo rằng tất cả các xe thực hiện IPainting nhưng không có đảm bảo rằng tất cả IPainting là xe ô tô.

Bạn có thể làm công việc này với một số tính năng truyền nhưng tôi nghĩ bạn nên cân nhắc lại thiết kế của mình.

AddCars(new Car[] { bmw, mercedes }); 
+0

Bạn nói đúng, nhưng tôi biết rằng điều này luôn đúng. Có cách nào để thực thi điều này không? Với một đối tượng Car đơn lẻ, tôi có thể dễ dàng truyền nó tới IPainting, vấn đề là tôi không thể làm tương tự cho các bộ sưu tập. – abenci

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