2010-08-03 15 views
42

En C# puede concatenar implícitamente una cadena y digamos, un entero:cadena = cadena + int: ¿Qué hay detrás de las escenas?

string sth = "something" + 0; 

Mis preguntas son:

  1. ¿Por qué, al asumir el hecho de que puede concatenar implícitamente una cadena y una int, C# no permite inicializar cadenas como esto:

    string sth = 0; // Error: Cannot convert source type 'int' to target type 'string' 
    
  2. ¿Cómo C# 0 arroja como cadena. ¿Es 0.ToString() o (string)0 o algo más?

  3. ¿Cómo encontrar la respuesta a la pregunta anterior?
+15

Me gusta particularmente cómo pregunta "¿Cómo encontrar una respuesta a la pregunta anterior?" –

Respuesta

44

Se compila a una llamada a String.Concat(object, object), como este:

string sth = String.Concat("something", 0); 

(Tenga en cuenta que esta línea en particular en realidad será optimizado de distancia por el compilador)

se define este método como sigue: (Tomado de la fuente de referencia .Net)

public static String Concat(Object arg0, Object arg1) { 
     if (arg0==null) { 
      arg0 = String.Empty; 
     } 

     if (arg1==null) { 
      arg1 = String.Empty; 
     } 
     return Concat(arg0.ToString(), arg1.ToString()); 
    } 

(Esto requiere String.Concat(string, string))


Para descubrir esto, se puede utilizar ildasm, o reflector (en IL o en C#, sin optimizaciones) para ver lo que la línea + compila a.

+6

SLaks es correcta, pero para exponer las preguntas del OP: 1) "+" es un operador sobrecargado entre la cadena y el objeto 2) Sí, .ToString() se llama en última instancia 3) Reflector –

+0

Y luego llama 'ToString' en ambos objetos ... –

+0

Véase también [esta respuesta] (http://stackoverflow.com/questions/3312504/why-is-there-no-exception-when-adding-null-to-a-string/3312509# 3312509). – SLaks

20

Esto se especifica en la sección 7.8.4 de la C# 4 spec:

Para una operación de la forma x + y, binario resolución sobrecarga operador (§7.3.4) se aplica para seleccionar un implementación específica del operador. Los operandos se convierten a los tipos de parámetro del operador seleccionado, y el tipo del resultado es el tipo de retorno del operador.

Los operadores de adición predefinidos son que se enumeran a continuación. Para los tipos de enumeración numérica y , los operadores de suma predefinidos calculan la suma de los dos operandos. Cuando uno o ambos operandos son de tipo cadena, los operadores de adición predefinidos concatenan la representación de cadena de los operandos.

La última frase es la más relevante para esta situación.

Luego, más tarde:

concatenación de cadenas

string operator +(string x, string y); 

string operator +(string x, object y); 

string operator +(object x, string y); 

Estas sobrecargas del binaria + operador realizar la concatenación de cadenas. Si un operando de concatenación de cadenas es nulo, una cadena vacía es sustituida. De lo contrario, cualquier argumento que no sea de cadena se convierte a su cadena de representación invocando el método virtual ToString heredado del objeto tipo . Si ToString devuelve nulo, se sustituye una cadena vacía .

Eso especifica cómo el número entero se convierte en una cadena.

Y el resultado:

El resultado de la concatenación de cadenas operador es una cadena que consta de los caracteres del operando de la izquierda seguido de los caracteres del operando derecho . El operador de concatenación de cadena nunca devuelve un valor nulo de .

El medio real de realizar la concatenación es específico de la implementación, pero como se señala en otras respuestas, la implementación de MS usa string.Concat.

+0

¿'' abc "+ 123' da como resultado que el' 123' esté encuadrado? ¿'' Abc "+ 123.ToString()' sería mínimamente más eficiente? – andleer

+2

@andleer: Es específico de la implementación, pero sí, lo hace ... así que en teoría, '123.ToString()' sería más eficiente, pero es posible que el JIT conozca este patrón. –

+0

El punto de referencia crudo con 25 millones de iteraciones muestra que 'ToString()' es aproximadamente un 7% más rápido. Framework 4.5.1 y como dije, crudo (pero mensurable). – andleer