Ich habe versehentlich einen Konstruktor in C # wie folgt überladen:
%Vor% Mit diesem Code wurde mein Projekt gut zusammengestellt. Wenn ich den Konstruktor nur mit einem string
-Argument aufruft, wie entscheidet C #, welchen Konstruktor ich verwenden möchte? Warum ist diese Funktionalität syntaktisch erlaubt?
Warum ist diese Funktionalität syntaktisch erlaubt?
In Bezug auf die generierte IL ist der zweite Konstruktor immer noch zwei Argumente. Der einzige Unterschied ist, dass das zweite Argument ein Attribut hat, das den Standardwert liefert.
Was den Compiler betrifft, ist der erste technisch immer noch besser geeignet, wenn Sie einen Konstruktor mit einer einzigen Zeichenfolge aufrufen. Wenn Sie dies mit einem einzigen Argument aufrufen, ist die beste Übereinstimmung der erste Konstruktor, und die zweite wird nicht aufgerufen.
Die C # -Spezifikation sagt dies aus. In 7.5 gibt es an, dass "... Instanzkonstruktoren Überladungsauflösung verwenden, um zu bestimmen, welche einer Kandidatenmenge von Funktionsmember aufgerufen werden soll." Die spezifischen Regeln werden dann in 7.5.3.2 spezifiziert, wo diese spezifische Regel gilt:
Andernfalls, wenn alle Parameter von MP ein entsprechendes Argument haben, während Standardargumente für mindestens einen optionalen Parameter in MQ ersetzt werden müssen, dann ist MP besser als MQ.
In diesem Fall hat MP (Ihr erster Konstruktor) alle Argumente, aber MQ (Ihre Sekunde) benötigt "mindestens einen optionalen Parameter".
Von MSDN : (Hervorhebung hinzugefügt)
Wenn zwei Kandidaten gleich gut bewertet werden, geht die Präferenz an einen Kandidaten, der keine optionalen Parameter hat, für die im Aufruf Argumente weggelassen wurden. Dies ist eine Folge einer allgemeinen Präferenz bei der Überladungsauflösung für Kandidaten, die weniger Parameter haben.
Die Verwendung von benannten und optionalen Argumenten wirkt sich auf die Überladungsauflösung in der folgende Möglichkeiten:
Eine Methode, ein Indexer oder ein Konstruktor ist jeweils ein Kandidat für die Ausführung seiner Parameter ist entweder optional oder entspricht, namentlich oder durch Position, zu einem einzigen Argument in der aufrufenden Anweisung, und das Argument kann in den Typ des Parameters konvertiert werden.
Wenn mehr als ein Kandidat gefunden wird, gelten die Regeln für die Überladungsauflösung für bevorzugte Konvertierungen werden auf die Argumente angewendet, die explizit sind angegeben. Ausgelassene Argumente für optionale Parameter werden ignoriert.
Wenn zwei Kandidaten als gleich gut beurteilt werden, geht die Präferenz zu a Kandidat, der keine optionalen Parameter für die Argumente hat wurden in dem Aufruf weggelassen. Dies ist eine Konsequenz eines Generals Präferenz in Überladung Auflösung für Kandidaten, die weniger haben Parameter.
Zitiert von MSDN .
Ich wette, es wird die erste als geeigneter auswählen.
Die Verwendung von benannten und optionalen Argumenten wirkt sich auf die Überladungsauflösung folgendermaßen aus:
Eine Methode, ein Indexer oder ein Konstruktor ist ein Kandidat für die Ausführung if jeder seiner Parameter ist entweder optional oder entspricht dem Namen oder nach Position, zu einem einzelnen Argument in der aufrufenden Anweisung, und das Argument kann in den Typ des Parameters konvertiert werden.
Wenn mehr als ein Kandidat gefunden wird, gelten die Regeln für die Überladungsauflösung für
bevorzugte Konvertierungen werden auf die Argumente von
angewendet
explizit angegeben. Ausgelassene Argumente für optionale Parameter sind
ignoriert.
Wenn zwei Kandidaten als gleich gut beurteilt werden, geht die Präferenz zu a
Kandidat, der keine optionalen Parameter hat, für die
Argumente wurden in dem Aufruf weggelassen. Dies ist eine Konsequenz eines
allgemeine Präferenz in Überladungsauflösung für Kandidaten, die ein
haben
weniger Parameter.
Methode mit optionalem Parameter wird durch Überladung ausgeblendet.
Es gibt sogar eine ReSharper-Regel, die dich warnt.
Und hier finden Sie nützliche Diskussionen darüber, warum das erlaubt ist. Manche Leute denken sogar, dass es überhaupt kein Problem ist.
Tags und Links c# constructor compiler-construction overloading