2009-09-21 37 views
9

Tôi có một vài lớp:IList <Type> để IList <BaseType>

class Vehicle 
{ 
} 

class Car : Vehicle 
{ 
} 

Tôi có một danh sách các lớp có nguồn gốc: IList<Car> cars;

Tôi muốn chuyển đổi danh sách để lớp cơ sở của nó, và có đã thử: IList<Vehicle> baseList = cars as IList<Vehicle>;

Nhưng tôi luôn nhận được null. Cũng

cars is IList<Vehicle> evaluates to be false. 

Cấp, tôi có thể thêm các mục vào danh sách nếu tôi làm như sau:

List<Vehicle> test = new List<Vehicle>(); 

foreach (Car car in cars) 
{ 
    test.Add(car); 
} 

Và tôi nhận được danh sách của tôi, nhưng tôi biết đó có phải là một cách tốt hơn. Bất kỳ suy nghĩ nào?

+1

Liên quan đến http://stackoverflow.com/questions/981570/c-no-implict-conversion-from-classchild-to-classbase và http://stackoverflow.com/questions/1296892/c-interface-implementation -and-generic-collections-question ít nhất. –

+0

Robert Harvey: Tất nhiên có một cách khác; anh ta có thể tạo ra một triển khai thực hiện IList về cơ bản là một trình bao bọc trên một IList hiện có. Bằng cách này, anh ta sẽ không phải đúc tất cả các yếu tố, chỉ những thứ cần thiết. –

Trả lời

18

Sử dụng IEnumerable<T>.Cast:

IList<Vehicle> vehicles = cars.Cast<Vehicle>().ToList(); 

Ngoài ra, bạn có thể để tránh việc chuyển đổi vào danh sách tùy thuộc vào cách bạn muốn xử lý các danh sách nguồn xe.

+0

@Robert Harvey: .Net Framework 3.5 đã được phát hành gần hai năm trước.Tôi nghĩ rằng nó là an toàn để giả định rằng tất cả mọi người có nó ngay bây giờ, trừ khi họ có một lý do rất tốt không. –

+5

Lưu ý rằng kết quả này trong một danh sách mới, không phải là một tham chiếu đến cùng một danh sách. – configurator

12

Loại đa hình cho phép bạn bỏ IList<Car> đến IList<Vehicle> là không an toàn, vì nó sẽ cho phép bạn chèn Truck vào số IList<Car> của mình.

+0

Anh ấy không cố gắng truyền nó, nhưng tạo một thể hiện danh sách mới. – recursive

+5

uh, không. Anh ta đang cố gán một danh sách (tham chiếu đến a) của kiểu cơ sở từ một danh sách (tham chiếu đến a) của kiểu dẫn xuất, và tự hỏi tại sao anh ta lại rỗng. Nếu anh ta cố gắng tạo ra một ví dụ mới, điều này sẽ hoạt động tốt. – Novelocrat

+1

Ồ, đúng vậy. Tôi không đọc đủ gần. – recursive

3

Dưới đây là một vài phương pháp sử dụng LINQ:

IList<Derived> list = new List<Derived>(); 
list.Add(new Derived()); 

IList<Base> otherlist = new List<Base>(from item in list select item as Base); 
IList<Base> otherlist2 = new List<Base>(list.Select(item => item as Base)); 
1
var vehicles = cars.OfType<IVehicle>() 
4

Bạn đang phải đối mặt với vấn đề rằng có đồng hạn chế và contravariance trong C#. Có một cách tiếp cận thú vị trong C# 4.0, được mô tả here at the very ending. Tuy nhiên, nó tạo ra một số hạn chế khác có liên quan đến vấn đề xe tải trong câu trả lời từ Novelocrat.

0

Nếu bạn phải sử dụng IList tất cả các đường đi, sau đó bạn đang trên may mắn và các câu trả lời trên có thể giúp bạn. Tuy nhiên, nếu bạn có thể sử dụng IList được đúc là IEnumerable và sau đó chỉ cần đúc lại tại đích là IList, điều đó sẽ hoạt động, vì IEnumerable có thể chấp nhận thực hành như vậy.

// At the source or at the model. 
IEnumerable<BaseType> list = new List<Type>(); 
// At the destination. 
IList<BaseType> castedList = (IList<BaseType>)list; 

Mặc dù, kể từ khi biên dịch không thể thực thi những điều này, bạn phải tự đảm bảo rằng các loại và các loại cơ sở thực sự phù hợp, tất nhiên.

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