2010-01-04 9 views
11

zur Liste, wenn ich Objecta haben, implementiert ISomeInterfaceConvert Liste der Objekte von Schnittstellen

warum kann ich dies nicht tun:

List<objectA> list = (some list of objectAs . . .) 

List<ISomeInterface> interfaceList = new List<ISomeInterface>(list); 

Warum kann ich in der Liste bleiben nicht in den interfaceList Konstruktor? Gibt es eine Problemumgehung?

Antwort

23

in C# 3.0 + .Net 3.5 und höher können Sie dieses Problem beheben die folgenden

List<ISomeInterface> interfaceList = new List<ISomeInterface>(list.Cast<ISomeInterface>()); 

der Grund, warum dies nicht der Fall funktioniert, dass der Konstruktor für List<ISomeInterface> in diesem Fall, indem Sie einen IEnumerable<ISomeInterface> nimmt. Der Typ der Listenvariablen ist jedoch nur in IEnumerable<objectA> umwandelbar. Auch wenn objectA in ISomeInterface konvertierbar ist, ist der Typ IEnumerable<objectA> nicht in IEnumerable<ISomeInterface> umwandelbar.

Dies ändert sich jedoch in C# 4.0, wodurch die Sprache um Co- und Contravarianz-Unterstützung erweitert wird und solche Konvertierungen ermöglicht werden.

+1

@itowlson, dies ist, was der Benutzer in der Probe macht. Sie gaben nicht an, dass das Hinzufügen-Verhalten ein Teil der gewünschten Lösung war. – JaredPar

+1

Sie meinen .NET 3.5, nicht C# 3.5. –

1

Dies wird in C# 4.0 behandelt, Sie können dies nicht direkt in C# 3.5 tun. Sie können jedoch eine neue Liste aus dieser Liste erstellen und einen Erweiterungsoperator oder foreach verwenden, um sauberer zu arbeiten, wenn auch langsamer als ein Cast für den Typ, der von Kovarianz Contravariance (immer erhalten Sie falsch) in C# 4 bereitgestellt wird.

+1

Siehe meinen Kommentar zu Jared - Es gibt keine solche Sache wie C# 3.5. –

+0

Arg, erinnert mich an den Beauracrat in Futurama. Obwohl das sagte Linq war eine Sprache ändern, und wurde nicht eingeführt, bis C# 3.5, so dass C# 2.0 war, bis es die Linq-Erweiterungen gegeben wurde, war WCF einfach ein Framework-Upgrade in 3.0. – Spence

3

einfachste & kürzeren Weg ist:

var interfaceList = list.Cast<ISomeInterface>().ToList() 

ODER

List<ISomeInterface> interfaceList = list.Cast<ISomeInterface>().ToList() 

Beide oben Beispielcodes sind gleich und Sie können jeden Sie verwenden ...

+0

Die rechte Seite mit der Verwendung von ToList() ist eine gute Idee! Aber beachte, dass du mit var den echten Typ der Variablen versteckst und es nicht gut ist, dies zu tun. Liste interfaceList = list.Cast (). ToList(); so ging ich diese Form als klarste, kürzeste Version verwenden –

+0

@ KovácsEde, nach dem Punkt, den Sie erwähnt, fügte ich zweite Format meiner Art zu dieser Antwort, aber beide von ihnen sind gleich. Wenn wir 'var' verwenden, schreiben wir tatsächlich unsere Codes in einem kürzeren Format, und immer können wir den Typ der Variablen erkennen, indem wir auf die rechte Seite von' = 'schauen. Auf der anderen Seite, selbst wenn wir 'var' verwenden, ist der' C# '- Compiler genug, um den reellen Typ der Variablen zu erkennen. Also, wenn Sie eine kürzere Syntax wollen, verwenden Sie 'var' und erkennen Sie den Variablentyp von den Codes auf der rechten Seite von' = 'sonst können Sie das zweite Format verwenden. – RAM