Null-Literal-Parametertyp Überladungsauflösung [duplizieren]

9

Dies ist eine Frage darüber, warum der Compiler eine bestimmte Überladung auswählt, wenn er ein Null-Literal als Parameter übergeben hat, was durch string.Format overloads demonstriert wird.

string.Format gibt ein ArgumentNullException bei Verwendung des Null-Literals für den args-Parameter aus.

%Vor%

Die Format-Methode hat einige Überladungen.

%Vor%

Wenn Sie den dekompilierten Code durchlaufen, wird die Ausnahme für die Null-Literalargumente von der zweiten Methode ausgelöst. Die folgenden Beispiele rufen jedoch die erste oben genannte Methode (wie erwartet) auf und rufen dann die zweite Methode auf, die die dritte Methode aufruft und schließlich nur "foo" zurückgibt.

%Vor%

Aber string.Format("foo {0}", null) ruft die zweite oben genannte Methode auf und führt zu einer Null-Ausnahme. Warum entscheidet der Compiler, dass das Null-Literal in diesem Fall der zweiten Methodensignatur und nicht der ersten entspricht?

    
Peter Kelly 13.09.2011, 09:29
quelle

2 Antworten

3

Ich würde einfach raten, dass object[] spezifischer ist als object und null zuweisbar ist, wenn object[] der erste ausgewählt ist. (7.5.3.2 Besserer Funktionsmember in den C # -Spezifikationen).

Dasselbe passiert, wenn Sie versuchen:

%Vor%     
InBetween 13.09.2011 09:47
quelle
0

Ich kann Ihnen nicht 100% Sicherheit geben, aber meine beste Schätzung wäre wie folgt ...

Wenn ich persönlich einen Compiler schreiben würde und ich mich damit abfinden müsste, welche überladene Funktion basierend auf übergebenen Parametern zu verwenden, würde ich natürlich die Liste wiederholen und die beste Übereinstimmung finden. Ich stelle mir vor, dass etwas in diese Richtung im C # -Compiler implementiert ist.

Das würde mir also nahelegen, dass entweder "overload 2" (in Ihrem Beispiel) früher in der Liste ist als "overload 1" und somit eine Übereinstimmung gefunden wird und die Iteration unterbrochen wird ODER der Compiler auf die Verwendung der mehr letztere passende Überladung.

Natürlich, in Ihrem Beispiel 2, indem Sie x und y passieren. Es ist leicht, mit "overload 1" übereinzustimmen, wenn Sie eine Zeichenkette mit einem Objekt abgleichen, während eine Zeichenkette nicht mit object [] übereinstimmen kann und daher "overload 2" keine gültige Übereinstimmung ist.

Wenn Sie NULL direkt übergeben, entspricht dies sowohl "overload 1" als auch "overload 2", also zurück zu dem Punkt, an dem Sie entweder der erste in der Liste oder der letzte gefundene Punkt sind.

EDIT: Es stellt sich also heraus, dass der Compiler essentiell entscheidet, welche Parameter spezifischer sind. Und Objekt [], wenn dieses Objekt spezifischer ist.

    
musefan 13.09.2011 09:51
quelle

Tags und Links