2009-09-21 14 views
9

Ich habe ein paar Klassen:IList <Type> zu IList <BaseType>

class Vehicle 
{ 
} 

class Car : Vehicle 
{ 
} 

Ich habe eine Liste der abgeleiteten Klasse: IList<Car> cars;

Ich möchte die Liste seiner Basisklasse konvertieren, und haben versucht: IList<Vehicle> baseList = cars as IList<Vehicle>;

Aber ich bekomme immer null. Auch

cars is IList<Vehicle> evaluates to be false. 

Zugegeben, kann ich die Elemente in einer Liste hinzufügen, wenn ich folgendes:

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

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

Und ich meine Liste, aber ich weiß, es muss einen besseren Weg sein. Irgendwelche Gedanken?

+1

Bezogen auf http://stackoverflow.com/questions/981570/c-no-implict-conversion-from-classchild-to-classbase und http://stackoverflow.com/questions/1296892/c-interface-implementation -und-generische-Sammlungen-Frage mindestens. –

+0

Robert Harvey: Natürlich gibt es einen alternativen Weg; Er könnte eine Implementierung von IList erstellen, die im Grunde eine Wrapper über eine vorhandene IList ist. Auf diese Weise würde er nicht alle Elemente werfen müssen, nur die, die benötigt werden. –

Antwort

18

Verwendung IEnumerable<T>.Cast:

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

Alternativ können Sie in der Lage sein, die Umstellung auf Liste zu vermeiden, je nachdem, wie Sie wollen die Quelle Auto-Liste zu verarbeiten.

+0

@Robert Harvey: Das .Net Framework 3.5 wurde vor fast zwei Jahren veröffentlicht.Ich denke, es ist sicher anzunehmen, dass jeder es inzwischen hat, es sei denn, sie haben einen sehr guten Grund, es nicht zu tun. –

+5

Beachten Sie, dass dies zu einer neuen Liste und nicht zu einer Referenz auf die gleiche Liste führt. – configurator

12

Diese Art von Polymorphismus, die Sie unsicher werfen IList<Car>-IList<Vehicle> können ist, weil es Ihnen eine Truck in Ihrem IList<Car> einfügen lassen würde.

+0

Er versucht nicht, es zu werfen, sondern erstellt eine neue Listeninstanz. – recursive

+5

uh, nein. Er versucht, eine (Referenz auf eine) Liste des Basistyps aus einer (Referenz auf eine) Liste des abgeleiteten Typs zuzuordnen und fragt sich, warum er null erhält. Wenn er versuchte, eine neue Instanz zu erstellen, würde das gut funktionieren. – Novelocrat

+1

Oh, richtig. Ich habe nicht nahe genug gelesen. – recursive

3

Hier sind ein paar Ansätze Linq mit:

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

Sie vor dem Problem, dass es nur begrenzte Ko- und Kontravarianz in C# ist. Es gibt einen interessanten Ansatz in C# 4.0, beschrieben here at the very ending. In der Antwort von Novelocrat ergeben sich jedoch einige andere Einschränkungen, die mit dem Lkw-Problem zusammenhängen.

0

Wenn Sie IList alle die Art und Weise verwenden müssen, sind Sie dann aus Glück und die Antworten können Sie oben helfen. Wenn Sie jedoch eine IList verwenden können, die als IEnumerable gegossen und dann einfach am Zielort als IList wiedergegossen wird, würde das funktionieren, da IEnumerable eine solche Praxis akzeptieren kann.

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

Obwohl, da der Compiler diese Dinge nicht erzwingen können, müssen Sie manuell sicherstellen, dass die Typen und Basistypen in der Tat übereinstimmen, natürlich.

Verwandte Themen