Frage

Alles erbt von Objekt. Es ist die Grundlage der Vererbung. Alles kann implizit den Vererbungsbaum gegossen werden, das heißt.

object me = new Person();

Daher folgt diesen bis zu seinem logischen Schluss, eine Gruppe von Menschen wäre auch eine Gruppe von Objekten sein:

List<Person> people = new List<Person>();
people.Add(me);
people.Add(you);
List<object> things = people; // Ooops.

Mit Ausnahme, das wird nicht funktionieren, die Menschen, die .NET entworfen entweder übersahen dies, oder es gibt einen Grund, und ich bin nicht sicher, welche. Mindestens einmal habe ich in eine Situation kommen, wo dies nützlich gewesen wäre, aber ich hatte mit einer fiesen Hack (nur Subklassifizieren Liste einen Cast-Operator zu implementieren), um am Ende.

Die Frage ist: Gibt es einen Grund für dieses Verhalten? Gibt es eine einfachere Lösung das gewünschte Verhalten zu bekommen?

Für das Protokoll, ich glaube, die Situation, dass ich diese Art von Verhalten wollte, war eine allgemeine Druckfunktion, die durch den Aufruf ToString Listen von Objekten angezeigt () und Formatierung der Saiten schön.

War es hilfreich?

Lösung

OK, jeder, der Generika in .net verwendet hat, muss an einem Punkt oder einem anderen in diese ausgeführt haben.

Ja, intuitiv sollte es funktionieren. Nein, in der aktuellen Version der C # Compiler ist es nicht.

Eric Lippert hat eine wirklich gute Erklärung für dieses Problem (es ist in elf Teilen oder etwas und biegen Sie an Orten dagegen, aber es ist auch die lesenswert). Siehe hier .

edit:

ausgegraben einen anderen entsprechenden Link, dieser beschreibt, wie Java diese abwickelt. Siehe hier

Andere Tipps

Sie können Linq verwenden Sie es zu werfen:

IEnumerable<Person> oldList = someIenumarable;
IEnumerable<object> newList = oldlist.Cast<object>()

Auf den ersten Blick das nicht intuitiv Sinn machen. Aber es tut. Schauen Sie sich diesen Code:

List<Person> people = new List<Person>();
List<object> things = people; // this is not allowed
// ...
Mouse gerald = new Mouse();
things.add(gerald);

Jetzt plötzlich haben wir eine List von Person Objekten ... mit einem Mouse drin!

Dies erklärt, warum die Zuordnung eines Objekt vom Typ A<T> auf eine Variable vom Typ A<S> nicht erlaubt ist, selbst wenn S ein übergeordneter Typ von T ist.

Die Linq Abhilfe ist ein guter. Eine andere Problemumgehung, da Sie Typ-Objekt verwenden, ist die Liste als IEnumerable passiert (nicht die generische Version).

Bearbeiten : C # 4 (derzeit Beta) unterstützt einen kovarianten Typparameter in IEnumerable. Während Sie nicht in der Lage sein wird, direkt zu einer List zuweisen, können Sie Ihre Liste an eine Methode übergeben ein IEnumerable erwartet .

Während das, was Ihr versucht, in der Tat logisch fließt, es ist eigentlich ein Merkmal, dass viele Sprachen unterstützen nicht nativ. Dies ist was co / contra Varianz genannt, die mit dem zu tun hat, wann und wie die Objekte von einer Sache zur nother von einem Compiler implizit gegossen werden können. Zum Glück, C # 4.0 wird Kovarianz und Kontra auf die C # Arena bringen, und solche impliziten Abgüsse wie dies möglich sein.

Für eine detaillierte Erklärung hierfür soll das folgende Channel9 Video hilfreich sein:

Mit Linq-Erweiterungsmethoden können Sie tun,

IEnumerable<object> things = people.Cast<object>();
List<object> things = people.Cast<object>().ToList();

Ansonsten, da Sie stark die Liste eingeben die implizite Konvertierung ist nicht erlaubt.

scroll top