2013-05-09 21 views
5

Ví dụ: tôi có một lớp cơ sở Entity, sau đó hai lớp phụ bắt nguồn từ điều này, LightEntityPlayerEntity.Lặp qua danh sách các đối tượng có cùng lớp cơ sở và trích xuất một lớp nhất định? Ví dụ:

Sau đó, tôi có List<Entity> Entities giữ LightEntity s và PlayerEntity s.

Tôi muốn nhận tất cả LightEntity s từ Entities.

tôi đã cố gắng:

List<LightEntity> lights = new List<LightEntity>(); 
foreach (Entity ent in Entities) 
{ 
    if(ent is LightEntity) 
    { 
     lights.Add(ent); 
    } 
} 

Nhưng nó không thích điều này như trình biên dịch vẫn dường như nghĩ rằng nó có thể cố gắng thêm chỉ là một Entity vào một danh sách các LightEntity.

Tôi đã cố gắng truyền ent đến LightEntity nhưng trình biên dịch cho biết không có phương pháp chuyển đổi số Entity thành số LightEntity.

+1

tôi muốn cho bạn biết nguyên nhân. Trong C#, downcasting không được cho phép ngầm. Điều này có nghĩa là bạn phải tiếp tục với việc truyền đạt rõ ràng, cho CLR biết rằng an toàn trong trường hợp của tôi là làm như vậy. – Nair

Trả lời

12

Bạn có thể sử dụng OfType để lọc các đối tượng theo loại:

List<LightEntity> lights = new List<LightEntity>(); 
lights.AddRange(entities.OfType<LightEntity>()); 

Hoặc thậm chí dễ dàng hơn:

List<LightEntity> lights = entities.OfType<LightEntity>().ToList(); 

Đọc thêm

+0

Đồng ý LINQ làm cho điều này rất đẹp :) –

+0

Tôi có nghe nói về Linq trước đây không? Tôi chỉ làm việc trên C# trong thời gian rảnh rỗi của tôi. – MatthewMcGovern

+0

Nói đúng cách đây không phải là LINQ nhưng tiện ích mở rộng IEnumerable – Steve

5

chỉ cast ent để (LightEntity) nên

Lights.Add((LightEntity)ent); 
+0

'InvalidCastException đã được bỏ cấm - Không thể truyền đối tượng loại PlayerEntity để nhập LightEntity' – MatthewMcGovern

+1

@MatthewMcGovern - Đặt dòng bên trong câu lệnh if. –

+0

Đó là lẻ bởi vì bạn đang kiểm tra xem ent là LightEntity. PlayerEntity có kế thừa từ LightEntity hay gì đó không? –

1

Bạn có thể làm điều đó với LINQ ...

var lights = Entities.Where(e => e is LightEntity) 
         .Select(e => (LightEntity)e) 
         .ToList(); 
0

Vâng, trước hết. Tôi không biết tại sao bạn đang làm điều này, nhưng tôi khá chắc chắn đây không phải là cách tốt nhất để giải quyết vấn đề của bạn. Có lẽ các lớp học có nguồn gốc của bạn không nên có cùng một lớp cơ sở hoặc một cái gì đó tương tự. Bạn nên cho chúng tôi bức tranh lớn hơn nếu bạn muốn được giúp đỡ.

Như đã được đăng, việc truyền là giải pháp cho vấn đề của bạn.

Lights.Add((LightEntity)ent); 
+0

Vâng, tôi bắt đầu tự hỏi nếu họ thực sự cần cùng một lớp cơ sở, họ chia sẻ rất nhiều mã thông thường (các hàm cập nhật cơ bản, hàm vẽ cơ sở, nhiều biến thành viên) và lưu trữ chúng trong cùng một danh sách bởi vì một thực thể có thể có nhiều thực thể con và tôi cần một cách để giữ chúng ở một nơi, để lưu trữ mối quan hệ và cập nhật chúng từ Parent-> Child – MatthewMcGovern

2

Vâng List (Of T) các giải pháp mở rộng đã được viết ra, vì vậy hãy để tôi chỉ cho cách này cũ thời

List<LightEntity> lights = new List<LightEntity>(); 
foreach (Entity ent in Entities) 
{ 
    LightEntity le = ent as LightEntity 
    if(le != null) 
    { 
     lights.Add(le); 
    } 
}