Der Compiler sagt Ihnen genau, was falsch ist: Sie können SomeClass
nicht implizit in T
konvertieren, aber es gibt wirklich zwei Dinge, auf die Sie achten müssen.
Die erste Sache ist, dass Sie nicht implizit in einen generischen Typ konvertieren können, da der Typ zur Kompilierzeit nicht bekannt ist. Sie müssen es explizit umsetzen oder - wenn Sie eine implizite Konvertierung benötigen - Vererbung verwenden.
Die zweite Sache ist, dass ein wenig mehr Typ Information benötigt wird (durch Einschränkungen), um zwischen Werttypen und Referenztypen zu unterscheiden. Im Moment weiß der Compiler nichts über T
. Es könnte auch eine int
sein, auf die nie ein class
geworfen werden kann.
Um einen Referenztyp T
zu werfen müssen Sie die class
Einschränkung, und es wird gut funktionieren:
public class SomeClass
{
public T Coerce<T>() where T : class
{
if (typeof(T) == typeof(SomeClass))
return this as T;
else throw new InvalidCastException();
}
}
Nun wird der Compiler verhindern, dass Sie auch von so etwas wie someClassInstance.Coerce<int>()
tun, und das ist der Punkt .
EDIT:
Wie für das Beispiel von (T)(object)this
, das funktioniert, weil man dann nicht mehr this
zu T
Gießen. Stattdessen wird this
an object
(das wird immer funktionieren, weil es ist, was alle andere Typen herrühren) und dann von object
zu T
, die aus dem gleichen Grund funktioniert. Sie umgehen die Kompilierzeitprüfungen.
Sie könnten dies tun und dann rufen Sie someClassInstance.Coerce<int>()
, würde es Ihnen die Ausnahme geben "Angegebene Besetzung ist nicht gültig." um Laufzeit. Wenn Sie jedoch eine generische Einschränkung verwenden, erhalten Sie die Warnung Kompilierzeit.
Wenn Sie das nicht stört, ist return (dynamic)this;
eine noch einfachere Lösung. Aber es vereitelt den Zweck der Verwendung von Generika.
Es würde wahrscheinlich helfen, wenn Sie erklären würden * was Sie hier erreichen *. –
'return (T) (Objekt) this;' – PetSerAl
Warum möchten Sie das tun? –