2012-05-02 19 views
9

¿Qué está pasando debajo?¿Por qué el número entero se convierte en cadena en este caso?

using System; 
using System.Collections.Generic; 
using System.Linq; 
using System.Text; 

public class DotNetPad 
{ 
    public static void Main(string[] args) 
    { 
     int i = 10; 
     string k = "Test"; 
     Console.WriteLine(i+k); 
     Console.WriteLine(k+i); 
    } 
} 

i se está convirtiendo a cadena en ambos casos. Me estoy confundiendo con la idea de la precedencia del operador (aunque este ejemplo no muestra mucho de eso) y la dirección de la evaluación. Algunas veces la evaluación ocurre de izquierda a derecha o viceversa. No sé exactamente la ciencia de cómo se evalúa la expresión ...

¿Por qué i se convierte en cadena en el ejemplo anterior y no proporciona un error de compilación?

Respuesta

23

A partir de la especificación C# - sección operador 7.7.4 Adición:

concatenación de cadenas:

string operator +(string x, string y); 
string operator +(string x, object y); 
string operator +(object x, string y); 

El operador binario + realiza concatenación de cadenas cuando uno o ambos operandos son de tipo cadena Si un operando de concatenación de cadenas es nulo, se sustituye una cadena vacía. De lo contrario, cualquier argumento que no sea de cadena se convierte a su representación de cadena invocando el método de ToString virtual heredado del tipo de objeto. Si ToString devuelve nulo, se sustituye una cadena vacía.

+2

Gracias - no se pudo llegar a la especificación rápidamente :) –

8

En ambos casos, tiene el operador + con la cadena como uno de los operandos. No hay operadores sobrecargados definidos por el usuario involucrados, por lo que el compilador usará ambos como situaciones de concatenación de cadenas.

Por lo que yo sé, el compilador de C# sólo no se va a utilizar la concatenación de cadenas para un escenario de x + y donde ya seax o y es una expresión string en tiempo de compilación si hay una sobrecarga definida por el usuario, por ejemplo, el operador XName operator +(XNamespace, string).

0

En realidad, el operador "+" es para concatenación. Hacer una concatenación entre un int y una cadena dará una cadena (con int automáticamente para encadenar)

+0

Usando "+" entre las variables numéricas en Console.WriteLine dará como resultado una suma de las variables numéricas en la salida. – SoEnLion

18

Me estoy confundiendo con la idea de la precedencia del operador y la dirección de evaluación.

No, no lo eres. Esto se confunde con frecuencia, sí, pero eso no es lo que está confundiendo porque ni la precedencia ni el orden de evaluación es relevante a la pregunta de si el entero se convierte a una cadena, o por qué es legal agregar un número entero a una cuerda.

A primera unconfuse que en el punto en el que reclama debe confundirse en adelante, las reglas son muy simples:

  • expresiones entre paréntesis están de acuerdo con la prioridad de los operadores y asociatividad.
  • subexpresiones se evalúan en orden de izquierda a derecha.

Eso es todo lo que necesita saber para hacerlo bien. Q Supongamos() devuelve un objeto que tiene un indexador con un setter, y los otros métodos de todos los números enteros de retorno:

Q()[R()] = A() * B() + C()/D(); 

que está entre paréntesis según la precedencia y asociatividad:

Q()[R()] = ((A() * B()) + (C()/D())); 

Y ahora cada subexpresión se evalúa de izquierda a derecha. Cada subexpresión, incluidas las subexpresiones que tienen subexpresiones. Por lo tanto, esto es equivalente al programa:

var q = Q(); 
var r = R(); 
var a = A(); 
var b = B(); 
var t1 = a * b; 
var c = C(); 
var d = D(); 
var t2 = c/d; 
var t3 = t1 + t2; 

y, finalmente, se establece el índice setter en q con índice ry valor t3.

Observe que cada subexpresión a la izquierda se evalúa antes de cada subexpresión a la derecha. A() * B() queda de C()/D(), por lo que sucede primero.

Esto no tiene nada que ver con su pregunta. Su pregunta se basa en un malentendido.

Quiero saber por qué se convierte en cadena en el ejemplo anterior, y en realidad no da un error de compilación

Ahí está su incomprensión. i es no se está convirtiendo en cadena. Se está convirtiendo a object. Su programa es exactamente equivalente a:

int i = 10; 
    string k = "Test"; 
    string t1 = System.String.Concat((object)i, (string)k); 
    Console.WriteLine(t1); 
    string t2 = System.String.Concat((string)k, (object)i); 
    Console.WriteLine(t2); 

Como se puede ver, no hay conversión de i de cadena en el primer lugar. i se convierte en objeto a través de una conversión de boxeo y luego pasa al método String.Concat. Ese método llama al object.ToString() en el entero encuadrado.

Así que trata de la primera mitad:

Quiero saber por qué se convierte en cadena en el ejemplo anterior, y en realidad no da un error de compilación

La segunda mitad es: ¿por qué no hay error de compilación?

¿Por qué debería haber un error de compilación? La especificación C# dice que puede agregar cualquier cadena a cualquier objeto, o cualquier objeto a cualquier cadena. Un int es un objeto y, por lo tanto, puede agregarlo a una cadena.

+0

Me gusta tu respuesta. Pero no estoy seguro de la última parte: si por especificación quieres decir que el operador + está definido de la manera en que @brokenglass ha mencionado, estaría de acuerdo ... – deostroll

Cuestiones relacionadas