Ich habe mich zwar damit abgefunden, dass es so ist. Weiss aber jemand ein einfache und logische Erklärung, wieso der nachfolgende Code sich nicht kompilieren lässt. Im Prinzip wäre eine Liste von "Sportwagen" auch eine liste von "Fahrzeugen", oder?
Class Fahrzeug End Class
Class Sportwagen Inherits Fahrzeug End Class
Class App Sub test() Dim aa As Fahrzeug Dim bb As Sportwagen = New Sportwagen aa = bb ' Das funktioniert und ist ja auch logisch'
Dim a As List(Of Fahrzeug) Dim b = New List(Of Sportwagen) a = b ' Das funktioniert nicht. Wieso denn?' ' System.Collections.Generic.List(Of Sportwagen) kann nicht in' ' System.Collections.Generic.List(Of Fahrzeug) konvertiert werden.' ' Verwenden Sie stattdessen' ' System.Collections.Generic.IEnumerable(Of Fahrzeug).'
Für das Warum hat m.fuchs bereits eine Antwort gegeben. Vielleicht kann ich beim Wie dann helfen. Hier könntest du die List<T>.ConvertAll<TOutput> Method verwenden.
Um das "warum" noch etwas zu vertiefen: stell Dir vor, Du reichst die Liste a an eine andere Methode weiter, die eine List<Of Fahrzeug> entgegennimmt. Und es gibt vielleicht auch noch LKWs. Die gerufene Methode sollte mit Fug und Recht erwarten können, dass sie in die Liste einen LKW einfügen darf. Wenn Du vorher aber b an a zugewiesen hast, ist es tatsächlich nur noch eine List<Of Sportwagen>, die keinen LKW aufnehmen kann. Es würde dann bei jemandem knallen, der gar nichts dafür kann. Deshalb ist das bis .NET 3.5 komplett unterbunden gewesen (für Generics, aber interessanterweise nicht für Arrays, nebenbei gesagt).
In .NET 4 gibt es neue Möglichkeiten, so etwas unter bestimmten Bedingungen zu erlauben. Für Details siehe die MSDN zu Ko- und Kontravarianz in .NET 4. Wenn ich es nicht gerade durcheinander bringe (kann es gerade nicht testen), müßte Dein Code in .NET 4 funktionieren, wenn a als IEnumerable<Fahrzeug> deklariert wird (denn mit IEnumerable kann das oben beschriebene Problem nicht auftreten, weil man einem IEnumerable nichts hinzufügen kann).
Ich glaub du hast da was falsch gelesen, wenn a = List(Of Fahrzeug) und b = List(Of Sportwagen) kann a = b nur List(Of Fahrzeug) sein und nicht List(Of Sportwagen). "string a = (double)1.1" ist ja auch vom Typ "string" und nicht "double". Immer der Linke Typ bleibt stehen.
schreibe, ist a als object deklariert und verweist auf einen String. Ich kann dann mit a alles machen, was mit object geht. Wenn in gleicher Weise
List<Fahrzeug> a = new List<Sportwagen>();
möglich wäre (und die Frage war ja, warum das nicht geht), würde a auf eine List<Sportwagen> verweisen, aber ich könnte damit alles machen, was mit List<Fahrzeug> geht, insbesondere Add(lkw). das wollte ich verdeutlichen. (Sorry für die C#-Syntax, aber das kann ich schneller und sicherer).
Falsch, da object und List<Fahrzeug> zwei föllig verschiedene Sachen sind. Du hast eine Liste vom Typ Fahrzeug und kein Variable vom object welche wie ein Variant funktioniert. Da Sportwagen von Fahrzeug abgeleitet ist, könnte in der Theorie a=b funktionieren und der Typ von a ändert sich nicht. Das geht nur bei dynamic und object Typen.
Korrektur, "object a = "1234";" bleibt vom Typ object, verweißt nur auf einen String. Nur bei dynamic ändert sich der Variablentyp meines wissens nach (wobei ich nocht nicht viel mit dynamic gearbeitet habe)