2016-06-23 15 views
4

ich die folgende Methode definiert haben:Parameter: (erforderlich, optional) vs (Pflicht-, optional)

void Write(string fileContent, string fileName, string container = StorageBlobContainers.ProfilePictures) 

Der Code ohne Probleme kompiliert, so schrieb ich den Code, um sie auszuführen (von a Different-Datei):

string json = JsonConvert.SerializeXNode(node); 
FileProcessor.Write(json, "productscontainer"); 

Aber es schien wie aus irgendeinem Grund es einfach nichts getan hat.
Nach ein paar Minuten des Ringens, um das Problem zu verstehen, habe ich es endlich gefunden. Irgendwo in der gleichen Klasse, gab es bereits eine Write Funktion wie folgt definiert:

void Write(string filePath, string container = StorageBlobContainers.ProfilePictures) 
{ 
    if (!File.Exists(filePath)) 
    return string.Empty; 
    ... 

Das verwirrte mich wirklich, wie es gut tat kompilieren, und natürlich macht es Sinn, als eine Methode hat drei Parameter Signatur und die Anderer hat 2, aber ist das nicht sehr zweideutig und/oder fehleranfällig? Für mich scheint keine der Methoden die "logische" zu sein. Warum wird der zweite über den anderen gewählt?

+0

"Warum wird das zweite über das andere gewählt?" - weil das die Regeln der Sprache sind. Wir können die Sprachspezifikation streichen, wenn Sie möchten, und auf die spezifischen Gründe hinweisen, die zu diesem Punkt geführt haben, aber es ist unwahrscheinlich, dass Sie weiterkommen. –

+0

Wie ist die 2. Methode keine logische Wahl? Sie rufen eine Methode mit 2 String-Parametern auf und die gewählte Methode ist diejenige mit 2 String-Parametern. Es ist eine perfekte Passform. –

+0

Beachten Sie außerdem, dass der Sprache nach Version 1 optionale Parameter hinzugefügt wurden und der bloße Vorgang des Zurückgehens auf alten Code und das Hinzufügen von Standardwerten nicht dazu geführt haben sollte, dass zuvor kompilierter Code nicht kompiliert oder eine andere Methode ausgewählt wurde. –

Antwort

0

Ja, Methodenauflösung kann schwierig sein, also immer daran denken, wenn Sie mehrere Überladungen schreiben. Sie sollten für Sie nicht mehrdeutig sein, wie sie jetzt sind. Der Compiler hat gerade die kürzeste Übereinstimmung ausgewählt, die genau so ist, wie es sollte, weil dies dokumentiert ist.

Es gibt zwei Dinge, die Sie tun können:

  • Benennen Sie eine der Methoden. Dies macht die Methodenauflösung für Sie und den Compiler zum Kinderspiel.
  • Den letzten für beide erforderlichen Parameter festlegen. Dies wird die Methodenauflösung wieder sehr deutlich machen: auf zwei gegen drei Parameter.
0

Es angegeben ist (in der Überladungsauflösung, Abschnitt 7.5.3 des C# specification):

7.5.3.2 Bessere Funktion Mitglied

Für die Zwecke der besseren Funktionselement zu bestimmen, ein Die abgespeckte Argumentliste A wird so konstruiert, dass sie nur die Argumentausdrücke in der Reihenfolge enthält, in der sie in der ursprünglichen Argumentliste erscheinen. Die Parameterlisten für die einzelnen Funktionselemente sind folgendermaßen aufgebaut:

• Das erweiterte Formular wird verwendet, wenn das Funktionselement nur in der erweiterten Form anwendbar war.

• Optionale Parameter ohne entsprechende Argumente aus der Parameterliste

• Die Parameter so neu angeordnet werden, entfernt werden, dass sie an der gleichen Position wie das entsprechende Argument in der Argumentliste auftreten.

(...

)

• Andernfalls, wenn alle Parameter von M P ein entsprechenden Argument haben, während Standardargumente für mindestens einen optionalen Parameter in M ​​ Q dann M P substituiert werden müssen, ist besser als M Q.

(etc.)

Also in Ihrem Fall, optionaler Parameter mit ein Argumente Rechnung auf der Überladungsauflösung getroffen werden, so dass die zweiten (mit dem optionalen Parameter), paßt insbesondere Ihre Aufruf (mit zwei Argumenten) als der erwartete (der drei hat), also als "besser"

0

In der C# -Spezifikation (je nach Version kann sich dies ändern) Abschnitt 1.6.6.5 beschäftigt sich mit Methodenüberladung. Auch diese Frage ist das gleiche wie das, was Sie fragen OVerload with optional parameters, die Links zu dem folgenden MSDN-Artikel MSDN

, die den entsprechenden Abschnitt enthalten

Wenn zwei Kandidaten beurteilt werden, ebenso gut sein, bevorzugt eine geht Kandidat, der keine optionalen Parameter hat, für die Argumente im Aufruf weggelassen wurden. Dies ist eine Folge einer allgemeinen Präferenz bei der Überladungsauflösung für Kandidaten, die weniger Parameter haben.