21 Stimmen

Liste der Objekte in Liste der Schnittstellen umwandeln

Wenn ich ObjektA habe, das ISomeInterface implementiert

warum kann ich das nicht tun:

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

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

warum kann ich keine Liste in den interfaceList-Konstruktor einfügen? Gibt es einen Workaround?

36voto

JaredPar Punkte 699699

In C# 3.0 + .Net 3.5 und höher können Sie dies wie folgt beheben

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

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

Dies ändert sich jedoch in C# 4.0, das der Sprache Unterstützung für Co- und Contravariance hinzufügt und solche Konvertierungen ermöglicht.

1 Stimmen

@itowlson, das ist es, was der Benutzer in dem Beispiel tut. Sie haben nicht angegeben, dass das Verhalten Hinzufügen Teil der gewünschten Lösung ist.

1 Stimmen

Sie meinen .NET 3.5, nicht C# 3.5.

10voto

Ramin Bateni Punkte 15165

Der einfachste und kürzeste Weg ist:

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

OR

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

Beide oben genannten Beispielcodes sind gleichwertig und Sie können jeden verwenden, den Sie wollen...

1 Stimmen

Die rechte Seite mit der Verwendung von ToList() ist eine gute Idee! Aber beachten Sie, dass Sie mit var den wirklichen Typ der Variablen verbergen und es ist keine gute Praxis, dies zu tun. List<ISomeInterface> interfaceList = list.Cast<ISomeInterface>().ToList(); also habe ich mich für diese Form als klarste und kürzeste Version entschieden

1 Stimmen

@KovácsEde, entsprechend dem von Ihnen erwähnten Punkt habe ich das zweite Format meiner Antwort hinzugefügt, aber beide sind gleich. Wenn wir verwenden var In der Tat schreiben wir unsere Codes in einem kürzeren Format, und wir können immer den Typ der Variablen erkennen, indem wir auf die rechte Seite von = . Andererseits, auch wenn wir die var die C# Der Compiler ist klug genug, um den tatsächlichen Typ der Variablen zu erkennen. Wenn Sie also eine kürzere Syntax wünschen, verwenden Sie var und erkennen den Variablentyp anhand der Codes auf der rechten Seite von = sonst können Sie das zweite Format verwenden.

2voto

Spence Punkte 27536

Dies wird in C# 4.0 behandelt, in C# 3.5 können Sie dies nicht direkt tun. Sie können jedoch eine neue Liste aus dieser Liste erstellen und einen Erweiterungsoperator oder foreach verwenden, um dies sauber zu tun, wenn auch langsamer als ein Cast auf den Typ, der von Kovarianz Kontravarianz (die immer falsch ist) in C# 4.

1 Stimmen

Siehe meinen Kommentar an Jared - es gibt kein C# 3.5.

0 Stimmen

Arg, das erinnert mich an die Beauracrat in Futurama. Obwohl Linq eine Sprachänderung war und erst mit C# 3.5 eingeführt wurde, war C# also 2.0, bis es die Linq-Erweiterungen erhielt, WCF war einfach ein Framework-Upgrade in 3.0.

0 Stimmen

@JonSkeet Es gibt jetzt seit etwa 10 Jahren.

CodeJaeger.com

CodeJaeger ist eine Gemeinschaft für Programmierer, die täglich Hilfe erhalten..
Wir haben viele Inhalte, und Sie können auch Ihre eigenen Fragen stellen oder die Fragen anderer Leute lösen.

Powered by:

X