Gegeben die folgende Klasse:
%Vor% Von der impliziten Umwandlung von Func<MyType>
nach MyType
nahm ich an, dass Folgendes möglich wäre:
Aber ich bekomme:
Die Methodengruppe 'MyTypeWrapper' kann nicht in den Nicht-Delegate-Typ 'Test.MyType' konvertiert werden. Wollten Sie die Methode aufrufen?
Was, leider für mich, wenn nach ( wie ich halb erwartet ) gesucht wurde, führte zu Tonnen c# implicit-conversion callback
Sie verwenden bereits die integrierte implizite Konvertierung von Methodengruppe zu Func<MyType>
.
Der Compiler führt nicht zwei implizite Konvertierungen auf einmal durch.
Sobald Sie eine explizite Umwandlung in Ihre Klasse haben, weiß der Compiler nach einer impliziten Umwandlung in einen beliebigen Typ, der explizit in Ihre Klasse eingefügt werden kann.
Das ist bedauerlich. Ich bin mir ziemlich sicher, dass Sie einen Compilerfehler gefunden haben, und dieser Abschnitt der Spezifikation ist extrem schwer zu lesen.
In Abschnitt 6.4.4 der C # 4-Spezifikation wird erklärt, warum Ihre implizite Konvertierung illegal ist.
Der Algorithmus geht so. Sehen Sie sich zunächst den Quellentyp und den Zieltyp an. Es gibt keinen Quelltyp, da eine Methodengruppe keinen Typ hat. Der Zieltyp ist MyType
. Suchen Sie also MyType
nach benutzerdefinierten impliziten Konvertierungen. Nun stellt sich die Frage: Was ist der Satz anwendbarer benutzerdefinierter Operatoren ..., die von einem Typ konvertiert werden, der S umfasst? S
ist der Quelltyp und wir haben bereits festgestellt, dass es keinen Quelltyp gibt . Dies ist also bereits ein Beweis, dass die Konvertierung fehlschlagen sollte. Aber selbst wenn der Compiler aus irgendeinem Grund entscheidet, dass Ihre Func<MyType>
Konvertierung anwendbar ist, lautet die Regel eine standardmäßige implizite Konvertierung ... wird durchgeführt . Methodengruppen-Conversions werden absichtlich nicht als Standardkonvertierungen klassifiziert.
Deshalb sollte es illegal sein.
Warum ist dann die explizite Besetzung legal?
Dafür gibt es keine Rechtfertigung. Dies scheint ein Fehler zu sein.
Das ist bedauerlich; viele Entschuldigungen für den Fehler. Ich werde es meinen ehemaligen Kollegen melden; Wenn sie eine Analyse haben, die mit meiner in Konflikt steht, werde ich die Antwort aktualisieren.
UPDATE: Meine früheren Kollegen haben mir mitgeteilt, dass das Spezifikationsproblem, bei dem angenommen wird, dass der Quellausdruck einen Typ hat, durch eine Neuformulierung in der nächsten Version der Spezifikation behoben wird. Noch kein Wort, ob das explizite Cast-Verhalten ein Bug ist.
Weil der C # -Compiler MyTypeWrapper
nicht in ein Func<MyType>(MyTypeWrapper)
konvertieren kann. Es gibt einen Unterschied zwischen einer Methodengruppe und einem tatsächlichen Delegierten.
Dies kompiliert und läuft gut:
%Vor%Es gibt eine implizite Konvertierung von einer Methodengruppe in einen Delegattyp, der dieser Gruppe entspricht, und Ihre benutzerdefinierte implizite Konvertierung von diesem Delegaten in einen Typ ist vorhanden. Die allgemeine Idee hier ist, dass der Compiler nur eine implizite Umwandlung in einer Reihe zu einer Zeit verwendet. Wenn es ein A hat und ein C braucht, sucht es nach Umwandlungen von A nach C, nicht von A zu irgendeinem Typ B und von diesem Typ zu C. Dieser Algorithmus geht von O (n) zu O (n ^ 2) (nicht zu erwähnen, möglicherweise für Programmierer ziemlich verwirrend).
Der Grund, warum Ihr Code bei der Verwendung einer expliziten Umwandlung in MyType
funktioniert, ist, dass Sie keine impliziten Conversions mehr verketten.
Die Signatur von MyTestMethod
PASST die Signatur von Func<MyType>
, ist aber KEINE Func<MyType>
. Func hat einige implizite Umwandlungen selbst definiert, um Ihnen zu erlauben, solche Methoden wie Funcs zuzuweisen, aber Sie müssen explizit nach der Anwendung der Signatur suchen, weil der Compiler implizite Umwandlungen nicht für Sie ketten wird:
Tags und Links c# implicit-conversion callback