2009-02-05 8 views
9

Il y avait un collègue de travail me demander cela, et dans mon état embrouillé du cerveau je ne pas de réponse:Cordes et ints, implicites et explicites

Pourquoi est-ce que vous pouvez faire:

string ham = "ham " + 4; 

mais pas:

string ham = 4; 

S'il y a une fonte/opération implicite pour la conversion de chaîne lorsque vous êtes concaténer, pourquoi ne pas la même chose quand Affect ning en tant que chaîne? (Sans surcharger l'opérateur, bien sûr)

Répondre

19

Lorsque concaténer le compilateur transforme la déclaration "ham" + 4 dans un appel à String.Concat, qui prend deux paramètres object, la valeur 4 est encaissée et ToString est appelé à ce sujet.

Pour l'affectation il n'y a pas de conversion implicite int à string, et vous ne pouvez donc pas 4 à un string sans conversion explicite. En d'autres termes, les deux affectations sont traitées très différemment par le compilateur, malgré le fait qu'elles semblent très similaires en C#.

+0

efficacement vrai, mais je ne sais pas ce qu'il appelle en fait la méthode concat ou génère un code équivalent. La référence semble indiquer le dernier. – tvanfosson

+0

Si vous regardez le code du mode de libération avec Reflector (paramétrez-le pour afficher IL), vous voyez qu'il appelle Concat. –

+0

Enfin, il est logique maintenant pourquoi je ne vois pas souvent les appels ToString() dans le rasoir. J'ai continué à penser que c'était une convention spéciale de code rasoir. – BVernon

0

La valeur du côté droit de la première expression est une chaîne, tandis que la valeur du côté droit de la deuxième expression ne l'est pas. La concatonation fournit la magie dans le premier scénario, où l'affectation ne fait rien de spécial. Dans le second scénario, l'affectation continue à jouer stupide.

2

Il n'y a pas de conversion implicite lors de la concaténation. La concaténation de chaîne se résout à un appel String.Concat, qui a une surcharge qui prend des objets. C'est cette surcharge qui effectue une conversion (explicite) en chaîne.

0

L'expression

"ham " + 4 

force une conversion implicite de 4 à une chaîne de caractères sur la base de la combinaison d'un type de chaîne et l'opérateur d'addition. Plus précisément, c'est une qualité de l'opérateur "+", et lorsque vous faites une surcharge d'opérateur, vous pouvez implémenter manuellement le même type de chose.

Un exemple similaire et moins évidente serait:

longue myNumber = Int64.MaxValue - 1;

Dans ce cas, "1" doit être évalué comme un entier de 32 bits mais il est implicitement converti. Vous pouvez vérifier la section 6.1 du langage C# pour une liste exhaustive des conversions implicites supportées par le compilateur. Edit: pour être clair, la section de spécification de langage i fait référence aux conversions implicites supportées par le compilateur, tandis que les opérateurs comme "+" peuvent avoir leurs propres conversions supportées.

+0

Il n'y a pas de conversion implicite d'int en chaîne. – jalf

+0

C'est correct. Il y a une conversion implicite liée à l'opérateur "+". –

+1

L'opérateur + n'est pas défini pour String. Le compilateur génère les appels correspondants à Concat à la place. –

4

opérateurs binaires + sont prédéfinis pour types numériques et chaîne. Pour les types numériques , + calcule la somme de ses deux opérandes .Lorsque l'un des opérandes ou les deux sont de type chaîne, + concatène les représentations de chaîne des opérandes .

Reference

L'opérateur d'affectation (=) stocke la valeur de son opérande à droite dans l'emplacement de stockage , la propriété ou indexeur désigné par son opérande gauche et retours la valeur comme résultat. Les opérandes doivent être du même type (ou l'opérande de droite doit être implicitement convertible au type de l'opérande de gauche).

Reference

Questions connexes