21

Ich habe zwei überladene Methoden, eine mit einem optionalen Parameter.Widersprüchliche überladene Methoden mit optionalen Parametern

void foo(string a) { } 
void foo(string a, int b = 0) { } 

jetzt nenne ich:

foo("abc"); 

Interessanterweise ist die erste Überladung genannt wird. Warum nicht die zweite Überlast mit optionalem Wert auf Null gesetzt?

Um ehrlich zu sein, hätte ich erwartet, dass der Compiler einen Fehler bringt, zumindest eine Warnung, um unbeabsichtigte Ausführung der falschen Methode zu vermeiden.

Was ist der Grund für dieses Verhalten? Warum hat das C# -Team das so definiert?

+2

Dies ist genau die Art von schlechtem Sprachdesign, die zu heimtückischen Bugs führt. Es könnte auch leicht von einem Insider für Unternehmensspionage ausgenutzt werden. Ich wünschte, sie würden die Sprache daran hindern, dies bereits zuzulassen. –

Antwort

27

Von MSDN:

If two candidates are judged to be equally good, preference goes to a candidate that does not have optional parameters for which arguments were omitted in the call. This is a consequence of a general preference in overload resolution for candidates that have fewer parameters.

14

Eine Überladung, bei der keine optionalen Parameter automatisch ausgefüllt werden müssen, wird einer solchen Voreinstellung vorgezogen. Es besteht jedoch keine solche Präferenz ist zwischen Füllung in ein Argument automatisch und füllt in mehr als einer - so zum Beispiel, wird dies dazu führen, einen Fehler bei der Kompilierung: würde

void Foo(int x, int y = 0, int z = 0) {} 
void Foo(int x, int y = 0) {} 
... 
Foo(5); 

Beachten Sie, dass Foo (5, 5) gelöst werden dem zweiten Verfahren, weil dann ist es keine optionalen Parameter erfordern automatisch ausgefüllt werden

aus dem Bereich 7.5.3.2 des # 4 spec C:.

Otherwise if all parameters of MP have a corresponding argument whereas default arguments need to be substituted for at least one optional parameter in MQ then MP is better than MQ.

denke ich, in den meisten Fällen ist dies das Verhalten, das die meisten Menschen erwarten würden, um ehrlich zu sein. Es wird komisch, wenn Sie Basisklassenmethoden in den Mix einführen, aber das war schon immer so.

+2

Danke für Ihre Antwort.Noch eine Frage bleibt: WARUM haben sie es so definiert? Gibt es einen Szenerio, in dem die Überladung mit dem optionalen Parameter sinnvoll ist? Es wird nie mit dem Standardwert aufgerufen, oder? Aber es kann zu unerwünschten Fehlern führen. Ich denke immer noch, dass der Compiler mindestens eine Warnung geben sollte. Und es gibt andere Beispiele, wo der Entwickler dem Compiler explizit sagen muss, dass er dessen bewusst ist, was er tut. Zum Beispiel, wenn ein Parameter in einer Methode als ref deklariert ist, muss ich auch explizit das Schlüsselwort ref im Methodenaufruf verwenden; Andernfalls wird es nicht kompiliert. – Thomas

+2

@Thomas: Ich fürchte, ich habe keine Antworten für die Begründung - obwohl Eric Lippert könnte. Ich möchte nicht, dass Sie mehr * Gepäck * zu dem aufrufenden Code hinzufügen müssen - schließlich besteht der Grund für die Standardparameter genau darin, * die Menge an Code, die Sie benötigen, zu reduzieren. –

7

Man stelle sich vor, wenn es das Gegenteil waren. Du hattest eine Bewerbung. Es hatte eine Methode:

void foo(string a) { } 

Everyting hat gut funktioniert. Jetzt möchten Sie mit einem optionalen Parameter eine weitere Überlast hinzufügen:

void foo(string a, int b = 0) { } 

Boom! Alle Methodenaufrufe gehen zu der neuen Methode. Wann immer du willst oder nicht. Das Hinzufügen einer Methodenüberladung kann zu falschen Methodenaufrufen in der gesamten Anwendung führen.

Aus meiner Sicht haben Sie in diesem Fall viel mehr Möglichkeiten, Ihren (oder jemand anderen) Code zu brechen.

Auch OptionalAttribute wurde in C# bis Version 4.0 ignoriert, aber Sie könnten es verwenden. Und einige Leute haben es in C# -Code verwendet, um bestimmte Interoperabilitätsszenarien mit anderen Sprachen wie Visual Basic oder für COM-Interop zu unterstützen. Jetzt verwendet C# es für optionale Parameter. Das Hinzufügen von Warnungen/Fehlern kann für diese Anwendungen eine bahnbrechende Änderung bedeuten.

Es gibt vielleicht noch andere Gründe, aber das kommt mir zuerst in den Sinn.

+4

Es sollte stattdessen eine Compilerfehler- oder Codeanalysewarnung angezeigt werden. – Monstieur

+0

@Locutus Sie scheinen den vorletzten Absatz von Alexandras Antwort nicht gelesen zu haben. – JLRishe