Wie konvertiert man ein generisches ListT in ein Interface basiertes ListT?

7

Ich bin sicher, dass mir etwas Einfaches fehlt, aber ich versuche, eine stark typisierte Liste von Objekten, die alle eine Schnittstelle implementieren, in eine Liste dieses Schnittstellentyps zu konvertieren.

Nachfolgend finden Sie ein Beispiel, um den Fehler zu demonstrieren:

%Vor%     
John 16.02.2010, 11:29
quelle

7 Antworten

13

Anstatt so zu spielen, versuche:

%Vor%

Sie benötigen dazu .NET 3.5. Ich glaube, die Cast-Erweiterung-Methode finden Sie in System.Linq.

    
Dave Markle 16.02.2010, 11:32
quelle
6

Sie können nicht. Weil List<T> und ILIst<T> nur Parameter des invarianten Typs unterstützen. Dies liegt daran, dass T sowohl für Eingabe- als auch Ausgabeparameter verwendet wird (z. B. Rückgabewerte). Andernfalls können Sie die Typsicherheit brechen.

Andere Schnittstellen (z. B. IEntumerable<T> ) erlauben eine gewisse Varianz.

Siehe Eric Lipperts Blog " Fabulous Adventures In Coding " zur Diskussion von Kontra- und Kovarianz. Insbesondere das Tag " Kovarianz und Kontravarianz ".

Bearbeiten, wurde gerade zum Blog "C # Frequently Asked Questions" hinzugefügt: Kovarianz und Kontravarianz FAQ

    
Richard 16.02.2010 11:34
quelle
4

Was Sie hier nennen, heißt generische Kovarianz und wird von c # 3 nicht unterstützt. Es wird jedoch von c # 4 (.NET 4 / VS 2010) unterstützt und Sie können hier mehr darüber lesen:

  

Abweichung in generischen Schnittstellen

Nachdem das gesagt wurde, ist IList<T> nicht kovariant (weil es T akzeptiert und exponiert). IEnumerable<T> hingegen ist kovariant (weil T nicht akzeptiert wird).

    
Richard Szalay 16.02.2010 11:40
quelle
2

Sie können dies nicht tun, da Sie auf diese Weise alle Arten von Sicherheit verlieren können. Zum Beispiel führt das Umwandeln von List<Shape> in List<object> dazu, dass Objekte der Art any zur Liste hinzugefügt werden können, was geradezu widersprüchlich ist.

    
Anton Gogolev 16.02.2010 11:34
quelle
0

Sie können auch Folgendes tun:

%Vor%

Oder wenn Sie dies in .NET 2.0 tun:

%Vor%     
Arnold Zokas 16.02.2010 11:35
quelle
0

Sie können nicht zwischen Listen von Typen umwandeln, auch wenn die Typen selbst konvertierbar sind. Sie müssen eine neue Liste erstellen und sie auffüllen, indem Sie entweder die ursprüngliche Liste durchlaufen oder ConvertAll verwenden. Siehe Ссылка für Beispielcode.

    
Rich Tebb 16.02.2010 11:38
quelle
0

Dies funktioniert, wenn Sie allShapes als IEnumerable

definieren

In C # 4.0 können Sie einfach allshapes = cubes

zuweisen

Für C # 3.5 können Sie allShapes = cubes verwenden. Wählen Sie (c = & gt; ((Shape) c));

Aber in jedem Fall müssen Sie IEnumerable anstelle von List

verwenden     
cellik 16.02.2010 11:57
quelle