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.
Gracias - no se pudo llegar a la especificación rápidamente :) –