PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : C# casts und generics


Buzzler
2011-03-29, 14:26:11
Angnommen ich habe Folgendes:

interface ISomeInterface
class SomeClass : ISomeInterface

Ich kann ohne Probleme (implizit) von SomeClass nach ISomeInterface casten, soweit alles klar und offensichtlich. Wenn ich nun aber sowas habe:

class SomeGenericClass<T> where T : ISomeInterface

Kann ich jetzt (explizit) von SomeGenericClass<SomeClass> nach SomeGenericClass<ISomeInterface> casten? Der Compiler erlaubt es, aber irgendwie würde ich es gerne genau wissen.

Sorry, wenn das 'ne blöde Frage ist, aber ich habe beim Googlen nur gefunden, dass es für Arrays gehen soll aber nix Allgemeines darüber.

PatkIllA
2011-03-29, 15:26:43
Geht nicht.
Evtl. kommst du mit Kovarianz & Contra-Varianz in .NET 4 weiter. Das muss aber explizit gekennzeichnet werden und geht nur mit generischen Interfaces bzw. delegates.
Beispiele im Framework sind IEnumerable<out T> oder IEqualityComparer<in T>

Monger
2011-03-29, 15:56:37
Hä? Natürlich geht das. Genau dazu sind Generic Constraints nunmal da.

Vererbung macht deutlich mehr Probleme. Sprich: SomeClass<ISomeInterface> ist keineswegs ein Subtypus von SomeClass<T>. Das ist nicht ganz intuitiv, aber der Compiler verbietet das völlig zu recht. Aber Generic Constraints sind erlaubt, und funktionieren auch.

PatkIllA
2011-03-29, 15:57:57
Hä? Natürlich geht das. Genau dazu sind Generic Constraints nunmal da.Darum geht es aber nicht.
Vererbung macht deutlich mehr Probleme. Sprich: SomeClass<ISomeInterface> ist keineswegs ein Subtypus von SomeClass<T>. Das ist nicht ganz intuitiv, aber der Compiler verbietet das völlig zu recht. Aber Generic Constraints sind erlaubt, und funktionieren auch.
Das hat mit den Constraint aber nichts zu tun.

In .NET 4. Geht jetzt folgendes:
IList<SomeClass> list = new List<SomeClass>();
IEnumerable<ISomeInterface> enumerable = list;

Buzzler
2011-03-29, 16:40:52
Geht nicht.Danke.
Evtl. kommst du mit Kovarianz & Contra-Varianz in .NET 4 weiter.Ist für das, was ich brauche, Overkill und das Ganze soll nach Möglichkeit erstmal bei 3.5 bleiben.

Ich habe es jetzt mit einer abstrakten Superklasse für SomeGenericClass<T> geregelt, die halt an einer Stelle einen upcast nach ISomeInterface machen muss. Ich darf nur nicht irgendwann auf beschränkte Ideen kommen und zusätzlich die Kommentare ignorieren. Ah, sense of foreboding *dramatische Musik* ... ;)

Sprich: SomeClass<ISomeInterface> ist keineswegs ein Subtypus von SomeClass<T>.Ja, das hätte mir eigentlich auch klar sein müssen, aber irgendwie habe ich zwischendurch immer mal einen Hirnfurz und dann entgehen mir solche "Details". :biggrin: Immerhin habe ich es diesmal aber geschafft, nicht in alte Gewohnheiten zurückzufallen und unbemerkt Teile prozedural zu programmieren, die ich dann schmerzhaft wieder aufräumen muss. :)

In .NET 4. Geht jetzt folgendes:{...}Wobei ich mir gar nicht mal so sicher bin, dass ich das so toll finde, dass das implizit geht.

PatkIllA
2011-03-29, 17:48:37
Wobei ich mir gar nicht mal so sicher bin, dass ich das so toll finde, dass das implizit geht.Ich finds gut. Ich mache aber auch ziemlich viel mit den IEnumerable. Insbesondere mit Linq und dem yield keyword gehen da viele schicke Sachen.