c# - programacion - ¿Por qué estas dos comparaciones tienen resultados diferentes?
posible comparacion de referencias no intencionada c# (4)
¿Por qué este código es verdadero?
new Byte() == new Byte() // returns true
pero este código devuelve falso
new Byte[0] == new Byte[0] // returns false
Debido a que el new Byte()
crea el tipo de valor, que se comparan por valor (de forma predeterminada, devolverá el byte
con el valor 0
). Y el new Byte[0]
crea una matriz, que es un tipo de referencia y se compara por referencia (y estas dos instancias de matriz tendrán referencias diferentes).
Vea el artículo sobre tipos de valores y tipos de referencia para más detalles.
Hay una sobrecarga del operador ==
en el que ambos operandos son de tipo byte
y se implementa para comparar el valor de cada byte; en este caso, tiene dos bytes cero, y son iguales.
El operador ==
no está sobrecargado para las matrices, por lo que se usa la sobrecarga que tiene dos operandos de object
(ya que las matrices son de tipo object
) en el segundo caso, y su implementación compara las referencias a los dos objetos. La referencia a las dos matrices es diferente.
Vale la pena señalar que esto no tiene nada (directamente) que ver con el hecho de que el byte
es un tipo de valor y los arrays son tipos de referencia. El operador ==
para byte
tiene semántica de valores solo porque hay una sobrecarga específica del operador con esa implementación. Si esa sobrecarga no existiera, entonces no habría sobrecarga para la que dos bytes serían operandos válidos, y como tal, el código no se compilaría en absoluto . Puede ver esto fácilmente creando una struct
personalizada y comparando dos instancias de ella con el operador ==
. El código no se compilará, a menos que proporcione su propia implementación de ==
para esos tipos.
La comparación de la referencia es en realidad la comparación de la dirección del puntero, que son diferentes por lo que el motivo es falso y la dirección del valor no importa si se compara el valor.
El compilador intenta almacenar el tipo de valor en los registros, pero debido al número limitado de registros ocurre el almacenamiento en Pila con los valores [Reference] mientras el Tipo de referencia está en la pila, pero el valor contiene una dirección de la dirección de memoria en el Heap.
La comparación aquí compara el valor presente en la pila que está en el primer caso para ambos, mientras que en el segundo caso son las direcciones del montón las que son diferentes.
Los bytes son tipos de valores en .NET, lo que significa que el operador ==
devuelve verdadero si y solo si los dos bytes tienen el mismo valor. Esto también se conoce como igualdad de valor .
Pero las matrices son tipos de referencia en .NET, lo que significa que el operador ==
devuelve verdadero si y solo si se refieren a la misma instancia de matriz en la memoria. Esto también se conoce como igualdad o identidad de referencia .
Tenga en cuenta que el operador ==
puede estar sobrecargado tanto para los tipos de referencia como para los de valor. System.String
, por ejemplo, es un tipo de referencia, pero el operador ==
para cadenas compara cada carácter en la matriz en secuencia. Consulte las Pautas para sobrecargar iguales () y Operador == (Guía de programación C #) .
Si desea probar si las matrices contienen exactamente los mismos valores (en orden), debería considerar usar Enumerable.SequenceEqual
lugar de ==
.