Warum wird C # nicht korrekt mit generisch überschriebenen Methoden verknüpft?

8

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 Typparameter C im generischen Typ oder in der Methode Something<T>.Do<C,S>(C, Expression<Func<C,S>>) verwendet werden. Es gibt keine implizite Referenzkonvertierung von ToolStripStatusLabel nach Control .

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?

    
realistschuckle 07.01.2011, 17:10
quelle

2 Antworten

11

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.

    
Jon Skeet 07.01.2011, 17:17
quelle
0

Ich denke, Sie müssen nur expliziter mit Ihrem Anruf sein:

%Vor%     
ilivewithian 07.01.2011 17:15
quelle

Tags und Links