Ich hatte gehofft, so etwas zu tun, aber es scheint in C # illegal zu sein:
public Collection MethodThatFetchesSomething<T>()
where T : SomeBaseClass
{
return T.StaticMethodOnSomeBaseClassThatReturnsCollection();
}
Ich erhalte einen Fehler bei der Kompilierung: "'T' ist ein 'Typparameter', der im angegebenen Kontext nicht gültig ist."
Wie kann ich bei einem generischen Typparameter eine statische Methode für die generische Klasse aufrufen? Die statische Methode muss unter Berücksichtigung der Einschränkung verfügbar sein.
Antworten:
In diesem Fall sollten Sie die statische Methode für den eingeschränkten Typ direkt aufrufen. C # (und die CLR) unterstützen keine virtuellen statischen Methoden. So:
... kann nicht anders sein als:
Das Durchlaufen des generischen Typparameters ist eine nicht benötigte Indirektion und wird daher nicht unterstützt.
quelle
return SomeBaseClass.StaticMethodOnSomeBaseClassThatReturnsCollection();
funktionieren? Wenn ja, möchten Sie das vielleicht zu Ihrer Antwort hinzufügen. Vielen Dank. Es hat bei mir funktioniert. In meinem Fall hatte meine Klasse einen Typparameter, also tat ich dasreturn SomeBaseClass<T>.StaticMethodOnSomeBaseClassThatReturnsCollection();
und das funktionierte.Um auf eine frühere Antwort einzugehen, denke ich, dass die Reflexion näher an dem liegt, was Sie hier wollen. Ich könnte 1001 Gründe nennen, warum Sie etwas tun sollten oder nicht, ich beantworte Ihre Frage einfach wie gestellt. Ich denke, Sie sollten die GetMethod-Methode für den Typ des generischen Parameters aufrufen und von dort aus fortfahren. Zum Beispiel für eine Funktion:
Dabei ist T eine Klasse mit der statischen Methode fetchAll ().
Ja, ich bin mir bewusst, dass dies schrecklich langsam ist und abstürzen kann, wenn someParent nicht alle untergeordneten Klassen zwingt, fetchAll zu implementieren, aber die gestellte Frage beantwortet.
quelle
Die einzige Möglichkeit, eine solche Methode aufzurufen, wäre die Reflexion. Es scheint jedoch möglich zu sein, diese Funktionalität in eine Schnittstelle zu packen und ein instanzbasiertes IoC / factory / etc-Muster zu verwenden.
quelle
Es hört sich so an, als würden Sie versuchen, mithilfe von Generika die Tatsache zu umgehen, dass es in C # keine "virtuellen statischen Methoden" gibt.
Leider wird das nicht funktionieren.
quelle
Ab sofort kannst du nicht. Sie müssen dem Compiler mitteilen, dass T über diese Methode verfügt, und derzeit gibt es keine Möglichkeit, dies zu tun. (Viele drängen Microsoft, das zu erweitern, was in einer generischen Einschränkung angegeben werden kann, sodass dies möglicherweise in Zukunft möglich sein wird.)
quelle
Hier poste ich ein Beispiel, das funktioniert, es ist eine Problemumgehung
quelle
public T : SomeBaseClass
dasIch wollte es nur rauswerfen, dass Delegierte diese Probleme manchmal lösen, je nach Kontext.
Wenn Sie die statische Methode als eine Art Factory- oder Initialisierungsmethode aufrufen müssen, können Sie einen Delegaten deklarieren und die statische Methode an die entsprechende generische Factory übergeben oder was auch immer diese "generische Klasse mit dieser statischen Methode" benötigt.
Beispielsweise:
Leider können Sie nicht erzwingen, dass die Klasse die richtige Methode hat, aber Sie können zumindest beim Kompilieren erzwingen, dass die resultierende Factory-Methode alles hat, was sie erwartet (dh eine Initialisierungsmethode mit genau der richtigen Signatur). Dies ist besser als eine Laufzeitreflexionsausnahme.
Dieser Ansatz hat auch einige Vorteile, dh Sie können Init-Methoden wiederverwenden, Instanzmethoden sein usw.
quelle
Sie sollten diese mit Reflexion tun können, wie beschrieben hierDa der Link tot ist, habe ich die relevanten Details in der Wayback-Maschine gefunden:
quelle