Ich habe die folgenden Klassen und Methoden definiert:
%Vor%Dies wird gut übersetzt. Woo hoo! Auf halbem Wege. Dann versuche ich es später mit Code wie folgt zu verwenden:
%Vor%Dies wird jedoch mit der folgenden Fehlermeldung beendet
Der Typ
ToolStripStatusLabel
kann nicht als TypparameterC
im generischen Typ oder in der MethodeSomething<T>.Do<C,S>(C, Expression<Func<C,S>>)
verwendet werden. Es gibt keine implizite Referenzkonvertierung vonToolStripStatusLabel
nachControl
.
Es scheint mir, dass der C # -Compiler in diesem Fall fehlgeschlagen ist, obwohl die beiden Methoden keinen Satz mehrdeutiger Methodendeklarationen erstellen. Control
und ToolStripStatusLabel
existieren als Geschwister in der Vererbungsstruktur von Component
. Ich würde denken, dass der Compiler genügend Informationen hätte, um den Methodenaufruf im Client-Code korrekt zu binden.
Wenn ich jedoch dasselbe mit meinen eigenen Geschwisterklassen mache, dann ist alles in Ordnung.
%Vor%Kann jemand etwas darüber aufklären, was ich falsch gemacht habe, wenn überhaupt?
Das Problem ist, dass die erste Methode in der Kandidatenmenge für die Überladungsauflösung ist, da die Typeinschränkung C : Control
erst angewendet wird, nachdem die Überladungsauflösung durchgeführt wurde. Ich glaube, Sie erwarten, dass es früh aussortiert wird - und das ist es nicht.
Wenn Sie nun C = ToolStripItem
behandeln, ist die erste Überladung spezifischer als die zweite - daher ist das Ergebnis der Überladungsauflösung, diese erste Version auszuwählen.
Die Validierungsvalidierung ist dann angewendet ... und schlägt fehl.
Ich habe einen Blogbeitrag zu diesem Thema was Ihnen helfen kann, den Prozess zu verstehen, und dann ein weiterer Blogpost , wo ich die Regeln auf ziemlich alberne Weise anwende.
EDIT: In Ihrem zweiten Beispiel ist der Typ des Arguments genau der Typ, der im ersten Parameter angegeben ist, so dass die erste Methode nicht spezifischer ist. Die zweite Methode gewinnt, weil weniger Typparameter vorhanden sind (ich denke, ich habe sie nicht im Detail überprüft) und dann validiert und übergeben.
Um es in ToolStripItem-Bedingungen zurückzuversetzen, könnten Sie Ihr erstes Beispiel mit einer einfachen Änderung kompilieren:
%Vor% Durch die Änderung des Kompilierungszeittyps toolStripItem
von ToolStripStatusLabel
nach ToolStripItem
wird der "Vorteil" der ersten Methode beseitigt, der dann kompiliert wird.
Ich denke, Sie müssen nur expliziter mit Ihrem Anruf sein:
%Vor%Tags und Links .net c# generics compiler-errors