Bizarre que cela puisse paraître, c'est tout simplement en suivant les règles du langage C# spec.
À partir de la section 7.3.4:
Une opération de la forme x op y, où op est un overloadable opérateur binaire, x est une expression de type X et y est une expression de type Y, est traité comme suit:
- L'ensemble des candidats définis par l'utilisateur opérateurs fournis par X et Y pour le fonctionnement de l'opérateur op(x, y) est déterminé. L'ensemble se compose de l'union du candidat opérateurs fournis par X et le candidat opérateurs fournis par Y, chaque déterminé en utilisant les règles du §7.3.5. Si X et Y sont du même type, ou si X et Y sont dérivées à partir d'une base commune, partagée candidat opérateurs se trouvent seulement dans l'ensemble une fois.
- Si l'ensemble des candidats défini par l'utilisateur des opérateurs n'est pas vide, alors cela devient de l'ensemble des candidats opérateurs pour l'exploitation. Sinon, le prédéfinies de l'opérateur binaire op mises en œuvre, y compris leur levée de formes, de devenir l'ensemble des candidats opérateurs pour l'exploitation. Les prédéfinis des implémentations d'un opérateur donné sont spécifiés dans la description de l'opérateur (§7.8 à travers §7.12).
- La résolution de surcharge règles du §7.5.3 sont appliquées à l'ensemble des candidats opérateurs de sélectionner le meilleur de l'opérateur à l'égard de la liste d'arguments (x, y), et cet opérateur devient le résultat de la surcharge du processus de résolution. Si la résolution de surcharge ne parvient pas à sélectionner un seul opérateur, une liaison se produit une erreur.
Donc, nous allons marcher à travers ce tour.
X est le type null ici - ou pas du tout, si vous voulez penser de cette façon. Ce n'est pas de fournir tout les candidats. Y est - bool
, ce qui n'est pas définie par l'utilisateur +
opérateurs. Donc, la première étape ne trouve pas définie par l'utilisateur opérateurs.
Le compilateur se déplace ensuite sur le deuxième point, en regardant à travers les prédéfinis opérateur binaire + implémentations et de leur levée de formes. Ces sont listées dans l'article 7.8.4 de la spécification.
Si vous regardez à travers ceux des opérateurs prédéfinis, le seul l'un qui est applicable est - string operator +(string x, object y)
. Si le candidat a une seule entrée. Qui fait le point final très simple... de résolution de surcharge sélectionne l'opérateur, en lui donnant une expression globale type d' string
.
Un point intéressant est que ce sera le cas même si il y a d'autres définis par l'utilisateur des opérateurs disponibles sur pas mentionner les types. Par exemple:
// Foo defined Foo operator+(Foo foo, bool b)
Foo f = null;
Foo g = f + true;
C'est très bien, mais il n'est pas utilisé pour un littéral null, parce que le compilateur ne sait pas regarder en Foo
. Il ne connaît que de considérer string
parce que c'est un prédéfini opérateur explicitement mentionnées dans la spécification. (En fait, c'est pas un opérateur défini par le type de chaîne... 1), cela signifie que l'on va à l'échec de compilation:
// Error: Cannot implicitly convert type 'string' to 'Foo'
Foo f = null + true;
Autres deuxième opérande types d'utiliser certains autres opérateurs, bien sûr:
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 - Vous demandez peut-être pourquoi il n'y a pas une chaîne opérateur+. C'est une question raisonnable, et je suis le seul à en deviner la réponse, mais considérer cette expression:
string x = a + b + c + d;
Si string
avait rien de spécial à-boîtier dans le compilateur C#, cela constituerait effectivement:
string tmp0 = (a + b);
string tmp1 = tmp0 + c;
string x = tmp1 + d;
Voilà donc créé deux inutiles intermédiaire des chaînes de caractères. Cependant, parce qu'il y a un soutien spécial dans le compilateur, c'est effectivement en mesure de compiler les ci-dessus:
string x = string.Concat(a, b, c, d);
qui peut créer juste une seule chaîne de exactement la bonne longueur, la copie de toutes les données exactement une fois. Nice.