Ayer mientras publicaba un ejemplo sobre variables por referencia y comparación de objetos -como respuesta a una pregunta hecha en un foro, me surgió el siguiente problema:
class Program
{
static void Main(string[] args)
{
object a = new object();
object b = a; // [1]
a = "test"; // [2]
Console.WriteLine(a == b);
}
}
Por algún motivo la expresión a == b
evalúa a falso, aún cuando se sabe que en [1] a y b deberían tener la misma referencia para el objeto creado en el paso anterior. En [2] asigno un string
para evitar problemas con el boxing/unboxing entre variables por referencia y por valor, he probado asignando otros objetos también pero sin ningún efecto sobre el resultado final.
Lo curioso de esto es que si se comenta [2], esta vez la expresión evalúa a verdadero, resultado que confirma que a y b tienen la misma referencia -cabe recordar que tanto el operador = como el método Equals sólo comparan referencias.
No sé si esto es un bug o feature, en todo caso, estaré muy agradecido si alguien me ahorra tiempo de búsqueda para absolver esta pequeña duda.
Nota: sé que es difícil que el código mostrado pueda aparecer en una determinada aplicación.
6 replies on “Variables por referencia”
Por supuesto que evalua falso: en [1] a y b tienen la misma referencia. En [2] estas liberando a de la referencia, pero b sigue manteniendo el objeto. Intenta con un ejemplo mas especifico, y luego de [2] imprime el valor de a y has un llamado tambien a alguna funcion o metodo del objeto b para que veas que te reponderá
La respuesta es muy sencilla, a apunta a nuevo objeto llamado Object() luego se hace que b apunte a es nuevo objeto, en [2] se hace que a apunte ahora a otro objeto distinto que es la cadena "test", por lo cual nunca pueden ser iguales.
Antes de 1
a -> object
en [1]
b -> object
en [2]
a -> "test"
por lo tanto no son iguales. Esto no funciona como los tipos & de C++.
Pues tienen razón, en realidad en [2] se asigna otra referencia.
Gracias por los comentarios.
todo esto viene a ser porque los strings son inmutables, strings son objetos especiales, cada vez que "cambias" un string, realmente estas apuntando hacia otro objeto nuevo
osea que si en vez de un string usaras una clase, por ejemplo:
class Test {
public string Prop2;
}
Test a = new Test();
Test b = a; // [1]
a.Prop2 = "test"; // [2]
Console.WriteLine(a == b);
eso si te regresa True
Estoy con Eber Irigoyen, al igual que pasa en java, se instancia una nueva clase de string cada vez que se modifica, ya que operacionalmente es mucho mas rentable que encontrar el cambio en el string modificarlo.