Falsche Überladung, die Compilerfehler verursacht

9

In VS2013 werden im folgenden Beispiel zwei verschiedene Fehler angegeben, wenn versucht wird, eine Funktion an den Konstruktor eines Worker zu übergeben. Dennoch sind Lambda-Funktionen mit demselben Prototyp in Ordnung.

Was mache ich falsch, und wie kann ich die Definition der Funktion GetA ändern, damit sie übergeben wird?

Um Verwechslungen mit ähnlich klingenden Fragen zu vermeiden, die durch Missverständnisse über die Klassenvererbung verursacht werden, habe ich in diesem Beispiel absichtlich jede Vererbung vermieden.

WorkerA kann nur einen Func<A> im Contructor akzeptieren. WorkerAorB ist flexibler und kann entweder ein Func<A> oder ein Func<B> akzeptieren. WorkerAandB ist am fähigsten und kann gleichzeitig eine Func<A> und eine Func<B> akzeptieren (oder beides). Es ist meinem echten Code am nächsten.

Wenn jedoch Code im Manager versucht, Worker zu instanziieren, funktioniert WorkerA wie erwartet, aber WorkerAorB gibt den Fehler:

  

Fehler CS0121: Der Aufruf ist zwischen den folgenden Methoden oder nicht eindeutig   Eigenschaften: 'WorkerAorB.WorkerAorB (System.Func & lt; A & gt;)' und   'WorkerAorB.WorkerAorB (System.Func & lt; B & gt;)'

WorkerAandB gibt

  

Fehler CS0407: 'Ein ManagerA.GetA ()' hat den falschen Rückgabetyp

In jedem Fall scheint der Compiler nicht in der Lage zu sein zu bestimmen, welche Überladung verwendet werden soll, wenn ein Verweis auf eine reale Funktion und nicht auf eine Lambda-Variable oder eine vorhandene Variable Func<A> und in den Fall WorkerAandB übergeben wird Es wählt eindeutig die WRONG-Überladung aus und gibt einen Fehler über den Rückgabetyp der übergebenen Funktion aus.

%Vor% %Vor%

Können die Funktionen GetA oder GetAstatic in irgendeiner Weise modifiziert werden, damit der Compiler die richtige Überladung erkennt oder nur lambdas und / oder explizit deklarierte Delegaten in diesem Kontext erlaubt sind?

  

Update: Einige Informationen, die ich im Beispiel weggelassen habe. In der Realität   Problem, Klassen A und B sind in der Tat verwandt.

%Vor%      

Auch bei weiterer Reflexion des eigentlichen Problems ein Anruf nach

%Vor%      

wie

%Vor%      

war tatsächlich äquivalent zu

%Vor%      

Also für das eigentliche Problem habe ich das Äquivalent zum Löschen des   zweiter Konstruktor im Beispielproblem, da sich herausstellt, dass die Überladung redundant ist.

     

In der Zwischenzeit habe ich die Antwort angenommen, die tatsächlich ein Potenzial hat   Lösung für das Problem (obwohl eine offensichtliche, die ich nicht erwähnen wollte   in der ursprünglichen Frage), obwohl es nicht war, was ich schließlich verwendete.

    
Steve 17.04.2015, 17:42
quelle

3 Antworten

1

Die Antwort wäre das:

%Vor%

Warum es ohne die Umwandlungen nicht funktioniert hat .... Scheint, dass für den Compiler GetA nicht vom Typ Func<A> ist, sondern nur ein method group

    
Sidewinder94 17.04.2015, 18:11
quelle
2

Der Hauptteil von Eric Lipperts Antwort hier , wie es für diese Frage gilt, scheint die "Overhead-Auflösung" zu sein berücksichtigt Rückgabetypen nicht. " Wenn Sie also Ihr Beispiel umschreiben, indem Sie jedes Func durch ein Action ersetzen, verschwinden die Fehler, da es jetzt nicht leere Argumentlisten gibt, durch die die Mehrdeutigkeit aufgelöst wird.

%Vor%     
Joe Farrell 17.04.2015 18:40
quelle
0

Das allgemeine Problem ist, warum würden Sie Code so schreiben? Ich sehe die hypothetische Natur des Problems, aber es sollte niemals in der realen Welt existieren, weil wir Funktionen schreiben sollten, die tatsächlich wie erwartet lesen:

%Vor%

Es gibt keine andere Möglichkeit, eine Funktion zum Abrufen einer Person nach ID zu schreiben, indem eine Funktion übergeben wird, die ein int zurückgibt.

Oder wenn Sie mehrere Konstruktoren erstellen, löst die Verwendung des korrekten objektorientierten Ansatzes ein Problem:

%Vor%

Aber direkt zu Ihrer Frage ..

  

Können die GetA- oder GetAstatic-Funktionen in irgendeiner Weise modifiziert werden, um dem Compiler zu helfen, die richtige Überladung zu erkennen, oder sind in diesem Kontext nur Lambdas und / oder explizit deklarierte Delegaten erlaubt?

Soweit ich weiß, kann es nicht auf die Funktionsdefinitionen, aber es kann auf seine Verwendung gemacht werden:

%Vor%     
Erik Philips 17.04.2015 18:12
quelle