Warum diese implizite Typumwandlung in C # scheitern?
-
22-09-2019 - |
Frage
Hintergrund:
Nehmen wir an, ich habe die folgende Klasse bekam:
class Wrapped<T> : IDisposable
{
public Wrapped(T obj) { /* ... */ }
public static implicit operator Wrapped<T>(T obj)
{
return new Wrapped<T>(obj);
}
public void Dispose() { /* ... */ }
}
Wie Sie sehen können, bietet es einen impliziten Typumwandlungsoperator für T
→ Wrapped<T>
. Letztlich würde Ich mag diese Klasse können wie folgt verwenden:
interface IX { /* ... */ }
class X : IX { /* ... */ }
...
IX plainIX = new X();
using (Wrapped<IX> wrappedIX = plainIX)
{
/* ... */
}
Problem:
Allerdings versagt die Typumwandlung in der obigen using
Klausel. Während ich ein new X()
direkt an wrappedIX
zuweisen kann, ich bin nicht zuweisen etwas vom Typ IX
es erlaubt. Der Compiler wird mit dem folgenden Fehler beschweren:
Compiler CS0266 Fehler: Kann nicht implizit Typ 'IX' auf 'Wrapped
' konvertieren. Eine explizite onversion existiert (sind Sie ein gegossenes fehlt?)
Ich verstehe das nicht. Was ist das Problem hier?
Lösung
Ich glaube, es ist, weil IX
eine Schnittstelle ist. Der Compiler denkt, dass vielleicht ein Wert vom Typ IX
bereits von Wrapped<IX>
abgeleitet werden könnte (auch wenn Wrapped<T>
verschlossen ist), so dass es nicht um die Umwandlung nicht verwendet.
Die Details sind ziemlich kompliziert, in den Abschnitten 6.4.3 und 6.4.4 der C # 3.0-Spezifikation. Im Grunde genommen, weil IX
eine Schnittstelle ist, ist es nicht „umfasst von“ irgendwelchen Typen, was bedeutet, ein später Schritt in 6.4.4 nicht.
Ich schlage vor, Sie einen nicht-generischen Typen Wrapped
mit dieser Methode zu erstellen:
public static Wrapped<T> Of<T>(T item)
{
return new Wrapped<T>(item);
}
Dann können Sie einfach schreiben:
using (Wrapped<IX> wrappedIX = Wrapped.Of(plainIX))
Grundsätzlich können Konvertierungen aus verschiedenen Gründen ein bisschen schwierig sein -. Einfache Methoden der Regel einfacher zu verstehen sind, IMO