2009-10-10 24 views
10

Ngay bây giờ tôi có một thiết lập lớp tương đối đơn giản:C# hành vi foreach với các lớp học có nguồn gốc?

class A{ 
//stuff 
} 
class B:A{ 
//more stuff 
} 
public List<A> ListOfObjects; 

Điều gì sẽ xảy ra nếu tôi làm

foreach(B i in ListOfObjects) 

tôi sẽ chỉ nhận được đối tượng thuộc loại B? Nó sẽ áp dụng một số phép thuật OO và chuyển đổi tất cả As sang Bs? Điều này thậm chí sẽ làm việc?

Trả lời

22

Nếu danh sách có A trong đó (hoặc những thứ khác không phải là B hoặc các lớp con của B), thì nó sẽ đơn giản phá vỡ với dàn diễn viên không hợp lệ. Bạn có thể muốn:

foreach(B i in ListOfObjects.OfType<B>()) {...} 

trong .NET 3.5. (Tôi giả định rằng danh sách chính nó sẽ là không null, btw)

3

danh sách foreach tất cả các đối tượng trong số trong bộ sưu tập. Nếu kiểu thời gian chạy của một mục không tương thích với kiểu biến lặp (trong trường hợp của bạn là loại B) thì một TypeCasException sẽ được ném ra.

Thay vào đó bạn có thể làm điều này:

foreach(A i in ListOfObjects) 
{ 
    B b = i as B 
    if (b!=null) .. 
} 

Hoặc bạn có thể lọc danh sách trước khi lặp lại nó. Giải pháp đơn giản nhất sẽ là truy vấn LINQ.

7

Cá nhân tôi sử dụng var làm biến vòng lặp trong foreach trong mọi trường hợp, để tránh bất kỳ khả năng diễn xuất thời gian chạy không hợp lệ nào. Bằng cách đó, loại biến vòng lặp sẽ là loại tĩnh của các mục của bộ sưu tập; nếu bạn muốn một cái gì đó khác, hãy sử dụng OfType để thực hiện tính năng lọc an toàn.

Some more explanation here.

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