Wenn ich es richtig gelesen ... dann ist das Problem, dass nur weil Foo : Bar
, dass nicht bedeutet, dass ISomething<Foo> : ISomething<Bar>
...
In einigen Fällen Varianz in C# 4.0 eine Option sein kann. Alternativ gibt es manchmal Dinge, die Sie mit generischen Methoden tun können (nicht sicher, dass es hier hilft).
Die nächstgelegene Sie tun in kann C# 3.0 (und darunter) ist wahrscheinlich ein nicht-generische Basis Schnittstelle:
interface IFolderOrItem {}
interface IFolderOrItem<TFolderOrItem> : IFolderOrItem
where TFolderOrItem : FolderOrItem { }
häufig, die Basis-Schnittstelle würde zum Beispiel ein Type ItemType {get;}
zu geben Sie den tatsächlich betrachteten Typ an. Dann Nutzung:
IFolderOrItem SelectedItem { get; set; }
...
public void SomeMagicMethod()
{
this.SelectedItem = GetMagicDocument(); // no cast needed
// not **so** bad
}
Von der Spezifikation bezieht sich dies auf §25.5.6 (ECMA 334 v4):
25.5.6 Konvertierungen
Konstruiert Typen folgen der gleichen Umwandlung Regeln (§13) wie nicht generische Typen. Bei der Anwendung dieser Regeln müssen die Basisklassen und die Schnittstellen der konstruierten Typen wie in §25.5.3 beschrieben festgelegt werden.
Es gibt keine speziellen Umwandlungen zwischen konstruierten Referenztypen außer die in §13 beschrieben. Insbesondere im Gegensatz zu Array-Typen, konstruiert Referenztypen erlauben nicht Co-Variante Umbauten (§19.5). Dies bedeutet, dass ein Typ List<B>
hat keine Umwandlung (entweder implizit oder explizit ) zu List<A>
selbst wenn B
ist von A
abgeleitet. Ebenso existiert keine Umwandlung von List<B>
zu List<object>
.
[Anmerkung: Die Begründung für ist dies einfach: Wenn eine Umstellung auf List<A>
erlaubt ist, dann offenbar, eine Werte vom Typ A
in die Liste zu speichern. Dies würde jedoch die invariant brechen, dass jedes Objekt in einer Liste vom Typ List<B>
ist immer ein Wert vom Typ B
oder auch unerwartete Ausfälle auftreten können, wenn sie in Collection-Klassen zuweisen. Endnote]
Das Gleiche gilt für Schnittstellen. Dies ändert ein Bit in C# 4.0, aber nur in einigen Fällen.
Was ist die Fehlermeldung, die es wirft? Zeit kompilieren? –
ohne einen Cast = Kompilierzeit; mit Cast = Laufzeit –
(Notiz per Kommentar zu meiner Antwort, habe ich einige Notizen auf einer nicht-generischen Basis-Schnittstelle, die es zumindest funktioniert) –