2010-05-25 22 views
9

Pruebe lo siguiente en la ventana Inmediato:C# == operador en la ventana Inmediato se comporta de manera diferente que en tiempo de ejecución

object a1 = "a"; 
object a2 = "a"; 
a1==a2 // outputs false 

y verá que a1 == a2 salidas false.

Sin embargo, en tiempo de ejecución, ya sea en una aplicación de ventana o consola, que obtendrá true:

object t1 = "a"; 
object t2 = "a"; 
MessageBox.Show((t1 == t2).ToString()); // outputs true 

El comportamiento de tiempo de ejecución es coherente con la definición para el operador == y cuerdas.

¿Alguien sabe si esto es un error en la ventana Inmediato?

+0

+1 solo porque nunca he visto la ventana Inmediato y parece clara! – RichK

Respuesta

15

Lo que está describiendo es comportamiento correcto.

La definición de == en Object compara las referencias de sus argumentos. Esto es diferente de la implementación de == para String que compara los valores de las cadenas. Los operadores en C# no son virtuales. Esto significa que, aunque sus objetos son realmente cadenas, porque el tipo estático es object se llama al == de Object, lo que significa que se realizará una comparación de referencia.

En C# las cadenas pueden ser interned en el grupo interno. Normalmente, cuando crea nuevas cadenas en tiempo de ejecución, recibe una referencia a un objeto de cadena completamente nuevo. Para obtener una cadena interna puede llamar al método string.Intern. Sin embargo, al compilar el código C#, las cadenas literales se internan automáticamente, por lo que si tiene la misma cadena literal en dos lugares del código, obtendrá una referencia al mismo objeto de cadena.

En la ventana inmediata las cadenas aparentemente no están intercaladas, se crean nuevas cadenas cada vez, incluso si tienen el mismo valor. Pero no hay ningún requisito en .NET de que todas las cadenas de caracteres se tengan que internar, por lo que no considero que se trate de un error.

Su código debe evitar depender de si las cadenas están intercaladas o no, ya que este es un detalle de implementación.

+3

Solo para aclarar las cosas para el OP: los operadores no participan en el polimorfismo, por lo que en ese caso es la implementación 'Object' de' == 'que se usa, no la implementación' String', de ahí este comportamiento inesperado. –

+0

No estoy de acuerdo con la declaración de "comportamiento correcto". El comportamiento de la ventana Inmediato no es coherente con la documentación de MSDN y con el tiempo de ejecución, ni siquiera consigo mismo cuando coloca un punto de corte y realmente prueba las variables que están presentes en el código. Personalmente creo que Microsoft debería arreglar esto. –

+0

@Damiano: ¿Qué quiere decir con: "El comportamiento de la ventana Inmediato no es consistente ... consigo mismo cuando pone un punto de corte y realmente prueba las variables que están presentes en el código"? ¿Puede dar un ejemplo? "El comportamiento de la ventana Inmediato no es coherente con la documentación de MSDN" ¿A qué parte específica de la documentación se refiere? –

2

Esto no es un error; El motivo por el que funciona el código de tiempo de ejecución es porque esas cadenas están intercaladas (es decir, hay solo una representación de esas secuencias de caracteres particulares en la memoria. Toda referencia a la constante "a" se refiere al mismo punto en la memoria). En la ventana inmediata, se crea una nueva cadena para cada uno, de modo que si bien su contenido es el mismo, los objetos apuntan a diferentes ubicaciones en la memoria.

Usando el operador == en un tipo de referencia realiza una comparación de referencia (a menos que se está haciendo referencia al tipo específico como el objeto, no lo que el objeto es -esto quiere decir object en este caso, no string --alters este comportamiento) Debido a que las cadenas literales compiladas están internados, tienen la misma referencia. Debido a que las cadenas de ventanas inmediatas son cadenas nuevas, no tienen la misma referencia.

2

Probablemente en tiempo de ejecución el compilador optimizará los literales de cadena para apuntar a la misma ubicación de referencia, pero en la ventana inmediata esta optimización no ocurre.

0

Sugeriría que si desactiva las optimizaciones, la versión NO INMEDIATA también devuelva falso. Como se dijo, esto no es un error, es una peculiaridad debido a las optimizaciones que ocurren dentro del compilador pero no dentro de la ventana inmediata.

Cuestiones relacionadas