Ist das ein Fehler?
Ja.
Herzlichen Glückwunsch, Sie haben einen Fehler in der Überlastungsauflösung gefunden. Der Fehler wird in C # 4 und 5 reproduziert. es wird in der "Roslyn" -Version des semantischen Analysators nicht reproduziert. Ich habe das C # 5-Testteam informiert und hoffe, dass wir dies vor der endgültigen Veröffentlichung untersuchen und lösen können. (Wie immer keine Versprechen.)
Eine korrekte Analyse folgt. Die Kandidaten sind:
0: C(params string[]) in its normal form
1: C(params string[]) in its expanded form
2: C<string>(string)
3: C(string, object)
Kandidat Null ist offensichtlich nicht anwendbar, da er string
nicht in konvertierbar iststring[]
. Das lässt drei.
Von den dreien müssen wir eine einzigartige beste Methode bestimmen. Dazu vergleichen wir die drei verbleibenden Kandidaten paarweise. Es gibt drei solche Paare. Alle von ihnen haben identisch Parameterlisten, sobald wir die ausgelassenen optionalen Parameter entfernt haben. Dies bedeutet, dass wir zu der in Abschnitt 7.5.3.2 der Spezifikation beschriebenen erweiterten Tiebreaking-Runde gehen müssen.
Welches ist besser, 1 oder 2? Der relevante Tiebreaker ist, dass eine generische Methode immer schlechter ist als eine nicht generische Methode. 2 ist schlechter als 1. 2 kann also nicht der Gewinner sein.
Welches ist besser, 1 oder 3? Der relevante Tiebreaker ist: Eine Methode, die nur in ihrer erweiterten Form anwendbar ist, ist immer schlechter als eine Methode, die in ihrer normalen Form anwendbar ist. Daher ist 1 schlechter als 3. Also kann 1 nicht der Gewinner sein.
Welches ist besser, 2 oder 3? Der relevante Tiebreaker ist, dass eine generische Methode immer schlechter ist als eine nicht generische Methode. 2 ist schlechter als 3. 2 kann also nicht der Gewinner sein.
Um aus einer Reihe von mehreren Kandidaten ausgewählt zu werden, muss ein Kandidat (1) ungeschlagen sein, (2) mindestens einen anderen Kandidaten schlagen und (3) der eindeutige Kandidat sein, der die ersten beiden Eigenschaften hat. Kandidat drei wird von keinem anderen Kandidaten geschlagen und schlägt mindestens einen anderen Kandidaten; Es ist der einzige Kandidat mit dieser Eigenschaft. Daher ist Kandidat drei der einzigartig beste Kandidat . Es sollte gewinnen.
Der C # 4-Compiler versteht es nicht nur falsch, da Sie richtig bemerken, dass er eine bizarre Fehlermeldung meldet. Dass der Compiler die Analyse der Überlastungsauflösung falsch macht, ist ein wenig überraschend. Dass die Fehlermeldung falsch ist, ist völlig überraschend. Die Fehlerheuristik "mehrdeutige Methode" wählt grundsätzlich zwei beliebige Methoden aus dem Kandidatensatz aus, wenn keine beste Methode ermittelt werden kann. Es ist nicht sehr gut, die "echte" Mehrdeutigkeit zu finden, wenn es tatsächlich eine gibt.
Man könnte vernünftigerweise fragen, warum das so ist. Es ist ziemlich schwierig, zwei Methoden zu finden , die "eindeutig mehrdeutig" sind, da die Beziehung "Betterness" intransitiv ist . Es ist möglich, Situationen zu finden, in denen Kandidat 1 besser als 2, 2 besser als 3 und 3 besser als 1 ist. In solchen Situationen können wir es nicht besser machen, als zwei davon als "die mehrdeutigen" auszuwählen.
Ich möchte diese Heuristik für Roslyn verbessern, aber sie hat eine niedrige Priorität.
(Übung für den Leser: "Entwickeln Sie einen linearen Zeitalgorithmus, um das eindeutige beste Mitglied einer Menge von n Elementen zu identifizieren, bei denen die Betterness-Beziehung intransitiv ist", war eine der Fragen, die mir am Tag meines Interviews für dieses Team gestellt wurden ein sehr harter Algorithmus; probieren Sie es aus.)
Einer der Gründe, warum wir das Hinzufügen optionaler Argumente zu C # so lange zurückgedrängt haben, war die Anzahl der komplexen mehrdeutigen Situationen, die in den Überlastungsauflösungsalgorithmus eingeführt werden. anscheinend haben wir es nicht richtig verstanden.
Wenn Sie ein Connect-Problem eingeben möchten, um es zu verfolgen, können Sie dies gerne tun. Wenn Sie nur möchten, dass wir darauf aufmerksam gemacht werden, halten Sie es für erledigt. Ich werde nächstes Jahr mit dem Testen fortfahren.
Vielen Dank, dass Sie mich darauf aufmerksam gemacht haben. Entschuldigung für den Fehler.
'Overloaded.ComplexOverloadResolution(string)'
bezieht sich auf die<string>(string)
Methode; Ich denke, es bezieht sich auf die(string, object)
Methode ohne Objekt geliefert.