So bizarr dies auch erscheinen mag, es folgt einfach den Regeln aus der C # -Sprachenspezifikation.
Aus Abschnitt 7.3.4:
Eine Operation der Form x op y, wobei op ein überladbarer binärer Operator ist, x ein Ausdruck vom Typ X ist und y ein Ausdruck vom Typ Y ist, wird wie folgt verarbeitet:
- Der Satz von benutzerdefinierten Kandidatenoperatoren, die von X und Y für den Operationsoperator op (x, y) bereitgestellt werden, wird bestimmt. Die Menge besteht aus der Vereinigung der von X bereitgestellten Kandidatenoperatoren und der von Y bereitgestellten Kandidatenoperatoren, die jeweils nach den Regeln von §7.3.5 bestimmt werden. Wenn X und Y vom gleichen Typ sind oder wenn X und Y von einem gemeinsamen Basistyp abgeleitet sind, treten gemeinsam genutzte Kandidatenoperatoren in der kombinierten Menge nur einmal auf.
- Wenn der Satz von benutzerdefinierten Kandidatenoperatoren nicht leer ist, wird dies zum Satz von Kandidatenoperatoren für die Operation. Andernfalls werden die vordefinierten Implementierungen des binären Operators op, einschließlich ihrer aufgehobenen Formen, zum Satz von Kandidatenoperatoren für die Operation. Die vordefinierten Implementierungen eines bestimmten Operators sind in der Beschreibung des Operators angegeben (§7.8 bis §7.12).
- Die Überlastungsauflösungsregeln von §7.5.3 werden auf die Menge der Kandidatenoperatoren angewendet, um den besten Operator in Bezug auf die Argumentliste (x, y) auszuwählen, und dieser Operator wird das Ergebnis des Überlastungsauflösungsprozesses. Wenn die Überlastungsauflösung keinen einzelnen besten Operator auswählt, tritt ein Bindungszeitfehler auf.
Lassen Sie uns dies der Reihe nach durchgehen.
X ist hier der Nulltyp - oder überhaupt kein Typ, wenn Sie es so sehen möchten. Es werden keine Kandidaten bereitgestellt. Y ist bool
, was keine benutzerdefinierten bereitstellt+
Operatoren . Der erste Schritt findet also keine benutzerdefinierten Operatoren.
Der Compiler fährt dann mit dem zweiten Aufzählungspunkt fort und betrachtet die vordefinierten Implementierungen des binären Operators + und ihre aufgehobenen Formen. Diese sind in Abschnitt 7.8.4 der Spezifikation aufgeführt.
Wenn Sie sich diese vordefinierten Operatoren ansehen, ist nur einer anwendbarstring operator +(string x, object y)
. Der Kandidatensatz hat also einen einzigen Eintrag. Das macht den letzten Aufzählungspunkt sehr einfach ... Überlastungsauflösung wählt diesen Operator aus und gibt einen Gesamtausdruckstyp von anstring
.
Ein interessanter Punkt ist, dass dies auch dann auftritt, wenn für nicht erwähnte Typen andere benutzerdefinierte Operatoren verfügbar sind. Beispielsweise:
// Foo defined Foo operator+(Foo foo, bool b)
Foo f = null;
Foo g = f + true;
Das ist in Ordnung, wird aber nicht für ein Null-Literal verwendet, da der Compiler nicht weiß, wie er nachsehen soll Foo
. Es muss nur berücksichtigt werden, string
da es sich um einen vordefinierten Operator handelt, der explizit in der Spezifikation aufgeführt ist. (Tatsächlich ist es kein Operator, der durch den Zeichenfolgentyp definiert ist ... 1 ) Das bedeutet, dass dies nicht kompiliert werden kann:
// Error: Cannot implicitly convert type 'string' to 'Foo'
Foo f = null + true;
Andere Typen von zweiten Operanden verwenden natürlich einige andere Operatoren:
var x = null + 0; // x is Nullable<int>
var y = null + 0L; // y is Nullable<long>
var z = null + DayOfWeek.Sunday; // z is Nullable<DayOfWeek>
1 Sie fragen sich möglicherweise, warum es keinen String + -Operator gibt. Es ist eine vernünftige Frage, und ich bin nur raten , auf die Antwort, aber bedenken Sie diesen Ausdruck:
string x = a + b + c + d;
Wenn string
der C # -Compiler kein spezielles Gehäuse hätte, wäre dies genauso effektiv:
string tmp0 = (a + b);
string tmp1 = tmp0 + c;
string x = tmp1 + d;
Das hat also zwei unnötige Zwischenzeichenfolgen erzeugt. Da es jedoch innerhalb der Compiler spezielle Unterstützung, es ist tatsächlich die Lage , die wie oben zu kompilieren:
string x = string.Concat(a, b, c, d);
Dadurch kann nur eine einzelne Zeichenfolge mit genau der richtigen Länge erstellt werden, wobei alle Daten genau einmal kopiert werden. Nett.