Generische Überladungsauflösung

7

Ich habe folgendes Szenario:

%Vor%

Und dann zwei Methoden

%Vor%

(Hinweis, der Code wurde im Browser geschrieben, beschreibt aber die Situation, der ich gegenüberstehe)

Wie kann ich die generische Methode aufrufen und B drucken?

Kann dies überhaupt ohne Reflexion getan werden? Ich habe einige Ideen, wie es mit der Reflexion gemacht werden könnte, aber ich suche nach einer saubereren Lösung, falls eine existiert.

Hinweis: Ich kann DoStuff generic nicht erstellen, da dies mit WCF verwendet wird und offene generische Typen nicht zulässig sind.

    
andreialecu 09.09.2010, 16:50
quelle

2 Antworten

17

(Ich nehme an, Sie verstehen bereits, warum das passiert. Wenn nicht, lesen Sie meinen Artikel zur Überladungsauflösung und lassen Sie es Ich weiß, ob es noch unklar ist.)

Wenn Sie C # 4 verwenden, könnten Sie dynamische Schreibmethoden verwenden:

%Vor%

Beachten Sie, dass dies nicht nur einen dynamischen Parameter hat. Die Idee ist, dass% foo oder einer Unterklasse auf immer beschränkt ist. co_de% zum Aufruf ... es ist nur so, dass die beste Methode zur Ausführungszeit bestimmt wird, nicht die Kompilierzeit.

Wenn Sie in pre-C # 4 stecken, könnten Sie es möglicherweise mit doppelter Versand tun:

%Vor%

Dann:

%Vor%     
Jon Skeet 09.09.2010, 16:55
quelle
16

Die Überladungsauflösung wird bei Kompilierzeit durchgeführt. Wenn "DoStuff" kompiliert wird, hat es bereits entschieden, welche Version von DoStuffImpl aufgerufen werden soll, und es entscheidet basierend auf den zur Kompilierungszeit verfügbaren Informationen nicht die zur Laufzeit verfügbare Information.

In C # gibt es vier Methoden zum Versenden von Methoden:

  • statisches Dispatching wählt eine statische Methode zum Zeitpunkt der Kompilierung. Zur Laufzeit wird die gewählte Methode aufgerufen.

  • Instanz-Dispatching wählt eine Instanzmethode zum Zeitpunkt der Kompilierung. Zur Laufzeit wird die gewählte Methode aufgerufen. (Dies ist die Form des Dispatchings, die bei nicht virtuellen Instanzmethoden und bei virtuellen Methoden verwendet wird, die mit "base" aufgerufen werden.)

  • virtuelles Dispatching wählt eine Instanzmethode zum Zeitpunkt der Kompilierung. Zur Laufzeit wird die übergreifendste Version dieser Methode für den Laufzeittyp des Objekts aufgerufen.

  • dynamisches Dispatching tut nichts zur Kompilierzeit (*). Zur Laufzeit startet der Compiler neu und führt zur Laufzeit eine Kompilieranalyse durch und generiert neuen Code, der geschrieben worden wäre, wenn Sie ihn überhaupt erst zur Kompilierzeit bekommen hätten. This ist genauso teuer wie es klingt; Glücklicherweise wird das Ergebnis zwischengespeichert, so dass Sie beim zweiten Aufruf nicht alle Kosten für Analyse und Codegen wieder bekommen.

Dynamisches Dispatching ist nur in C # 4 oder einer beliebigen Version von VB verfügbar.

(*) Das ist nicht ganz richtig; Es gibt einige Umstände, unter denen der Compiler eine Analyse zur Kompilierungszeit durchführen kann, selbst wenn die Argumente für die Methode dynamisch sind. Die Details sind kompliziert.

    
Eric Lippert 09.09.2010 16:56
quelle

Tags und Links