Considera este código:
int age = 25;
short newAge = 25;
Console.WriteLine(age == newAge); //true
Console.WriteLine(newAge.Equals(age)); //false
Console.ReadLine();
Ambos inty shortson tipos primitivos, pero una comparación con ==devuelve verdadero y una comparación con Equalsdevuelve falso.
¿Por qué?

Console.WriteLine(age.Equals(newAge));Equals()es en general.Respuestas:
Respuesta corta:
La igualdad es complicada.
Respuesta detallada:
Los tipos primitivos anulan la base
object.Equals(object)y devuelven verdadero si el recuadroobjectes del mismo tipo y valor. (Tenga en cuenta que también funcionará para los tipos anulables; los tipos anulables no nulos siempre encajonan en una instancia del tipo subyacente).Como
newAgees ashort, suEquals(object)método solo devuelve verdadero si pasa un short en caja con el mismo valor. Estás pasando un cuadroint, por lo que devuelve falso.Por el contrario, el
==operador se define como tomar dosints (oshortsolongs).Cuando se llama con una
inty unashort, el compilador convertir implícitamente elshortqueinty comparar el resultadoints por valor.Otras formas de hacerlo funcionar
Los tipos primitivos también tienen su propio
Equals()método que acepta el mismo tipo.Si escribe
age.Equals(newAge), el compilador seleccionaráint.Equals(int)como la mejor sobrecarga y se convertirá implícitamenteshortaint. Luego regresarátrue, ya que este método simplemente compara laints directamente.shorttambién tiene unshort.Equals(short)método, perointno se puede convertir implícitamenteshort, por lo que no lo está llamando.Podría forzarlo a llamar a este método con un yeso:
Esto llamará
short.Equals(short)directamente, sin boxeo. Siagees mayor que 32767, generará una excepción de desbordamiento.También podría llamar a la
short.Equals(object)sobrecarga, pero pasar explícitamente un objeto en caja para que obtenga el mismo tipo:Al igual que la alternativa anterior, esto generará un desbordamiento si no cabe en a
short. A diferencia de la solución anterior, lo encajonaráshorten un objeto, perdiendo tiempo y memoria.Código fuente:
Estos son los dos
Equals()métodos del código fuente real:Otras lecturas:
Ver Eric Lippert .
fuente
long == int, ¿intconvertido implícitamente a lalongderecha?int age = 25;aconst int age = 25;, entonces el resultado cambiará. Esto se debeintashortque en ese caso existe una conversión implícita de a . Ver Conversiones implícitas de expresión constante .==compara los tipos de referencia por referencia. Para los tipos de valor y para los tipos que se sobrecargan==, no lo hace.Porque no hay sobrecarga para
short.Equalseso acepta unint. Por lo tanto, esto se llama:objno es unshort... por lo tanto, es falso.fuente
Cuando pasas
intashort's Equals, pasasobject:fuente
Para los tipos de valor,
.Equalsrequiere que los dos objetos sean del mismo tipo y tengan el mismo valor, mientras que==solo prueba si los dos valores son iguales.Object.Equalshttp://msdn.microsoft.com/en-us/library/bsc2ak47(v=vs.110).aspx
fuente
==se usa para verificar una condición igual, se puede considerar como un operador (operador booleano), solo para comparar 2 cosas y aquí el tipo de datos no importa, ya que se realizaría una conversión de tipo yEqualstambién se usa para verificar condiciones iguales , pero en este caso los tipos de datos deberían ser los mismos. N Equals es un método, no un operador.A continuación se muestra un pequeño ejemplo tomado del que proporcionó y esto aclarará brevemente la diferencia.
en el ejemplo anterior, X e Y tienen los mismos valores, es decir, 1, y cuando usamos
==, devolverá verdadero, ya que en el caso de==, el compilador convierte el tipo corto en int y se da el resultado.y cuando usamos
Equals, se realiza la comparación, pero el compilador no realiza la conversión de tipos, por lo que se devuelve falso.Chicos, por favor avíseme si me equivoco.
fuente
En muchos contextos donde un método o argumento de operador no es del tipo requerido, el compilador de C # intentará realizar una conversión de tipo implícita. Si el compilador puede hacer que todos los argumentos satisfagan sus operadores y métodos agregando conversiones implícitas, lo hará sin quejarse, aunque en algunos casos (¡especialmente con pruebas de igualdad!) Los resultados pueden ser sorprendentes.
Además, cada tipo de valor tal como
intoshortrealmente describe tanto un tipo de valor como un tipo de objeto (*). Existen conversiones implícitas para convertir valores a otros tipos de valores y para convertir cualquier tipo de valor a su tipo de objeto correspondiente, pero los diferentes tipos de objetos no son implícitamente convertibles entre sí.Si uno usa el
==operador para comparar ayshortanint, elshortse convertirá implícitamente en anint. Si su valor numérico es igual al delint, elintal que se convirtió será igualintal que se compara. Sin embargo, si se intenta utilizar elEqualsmétodo en corto para compararlo con unint, la única conversión implícita que satisfaría una sobrecarga delEqualsmétodo sería la conversión al tipo de objeto correspondienteint. Cuandoshortse le pregunta si coincide con el objeto pasado, observará que el objeto en cuestión esintmás bien que unshorty, por lo tanto, concluirá que no puede ser igual.En general, aunque el compilador no se quejará, se debe evitar comparar cosas que no son del mismo tipo; Si uno está interesado en saber si la conversión de cosas a una forma común daría el mismo resultado, debería realizar dicha conversión explícitamente. Considere, por ejemplo,
Hay tres formas en que uno podría comparar una
inta unafloat. Uno podría querer saber:floatvalor más cercano posible conintelfloat?floatcoincide con elint?intyfloatrepresenta el mismo valor numérico.Si uno intenta comparar
intyfloatdirectamente, el código compilado responderá la primera pregunta; si eso es lo que pretendía el programador, sin embargo, estará lejos de ser obvio. Cambiar la comparación a(float)i == fdejaría en claro que se pretendía el primer significado, o(double)i == (double)fharía que el código respondiera a la tercera pregunta (y dejaría claro que eso era lo que se pretendía).(*) Incluso si la especificación de C # considera un valor de tipo, por ejemplo,
System.Int32como un objeto de tipoSystem.Int32, tal opinión se contradice con el requisito de que un código se ejecute en una plataforma cuya especificación considere valores y objetos que habitan universos diferentes. Además, siTes un tipo de referencia, yxes unT, entonces una referencia de tipoTdebería poder referirsex. Por lo tanto, si una variablevde tipoInt32contiene unaObject, una referencia de tipoObjectdebería poder contener una referencia avo su contenido. De hecho, una referencia de tipoObjectpodría apuntar a un objeto que contiene datos copiadosv, pero no avsí mismo ni a su contenido. Eso sugeriría que ningunovni su contenido es realmente unObject.fuente
the only implicit conversion which would satisfy an overload of the Equals method would be the conversion to the object type corresponding to intIncorrecto. A diferencia de Java, C # no tiene tipos primitivos y en caja separados. Está en cajaobjectporque esa es la única otra sobrecarga deEquals().float. Lanzar unfloata adoubleno creará mágicamente una nueva precisión.List<String>.Enumeratory un objeto de almacenamiento dinámico de tipoList<String>.Enumeratorson los mismos, pero la especificación de ECMA / CLI dice que son diferentes, e incluso cuando se usan en C # se comportan de manera diferente.iyffueron cada convertido adoubleantes de la comparación, se producirían 16777217.0 y 16777216.0, que compara como desigual. La conversiónifloatproduciría 16777216.0f, comparando igual af.bool SelfSame<T>(T p) { return Object.ReferenceEquals((Object)p,(Object)p);}. El tipo de objeto en recuadro correspondiente a un tipo de valor puede satisfacer el tipo de parámetro aReferenceEqualstravés de una transmisión de preservación de identidad ; sin embargo, el tipo de ubicación de almacenamiento requiere una conversión que no preserva la identidad . Si emitir unTaUproduce una referencia a algo diferente al originalT, eso me sugeriría que aTno es realmente unU.Equals () es un método de System.Object Class
Sintaxis: Public virtual bool Equals ()
Recomendación si queremos comparar el estado de dos objetos, entonces deberíamos usar el método Equals ()
como se indicó anteriormente, las respuestas == operadores comparan los valores son los mismos.
No te confundas con ReferenceEqual
Reference Equals ()
Sintaxis: public static bool ReferenceEquals ()
Determina si la instancia de objetos especificada es de la misma instancia
fuente
Lo que debe darse cuenta es que hacer
==siempre terminará llamando a un método. La pregunta es si llama==yEqualstermina llamando / haciendo las mismas cosas.Con los tipos de referencia,
==siempre verificará primero si las referencias son las mismas (Object.ReferenceEquals).Equalspor otro lado, puede anularse y verificar si algunos valores son iguales.EDITAR: para responder svick y agregar un comentario de SLaks, aquí hay un código IL
fuente
ints con == llamada? Sugerencia: no hay unoperator ==método paraInt32, pero hay uno paraString.==no solo hace magia, sino que finalmente simplemente llama a un método (la mayoría de los programadores probablemente nunca implementaron / anularon ningún operador). Tal vez podría haber agregado un comentario a su pregunta en lugar de agregar mi propia respuesta. Siéntase libre de actualizar la suya si siente que lo que dije es relevante.==en cuenta que en los tipos primitivos no es un operador sobrecargado, sino una función de lenguaje intrínseca que se compila con laceqinstrucción IL.== en primitivo
En comparación primitiva, el operador == se comporta de manera bastante obvia, en C # hay muchas sobrecargas de operador == disponibles.
Por lo tanto, en este caso no hay conversión implícita de
intashortperoshortaintes posible. Entonces newAge se convierte en int y se produce una comparación que devuelve verdadero ya que ambos tienen el mismo valor. Entonces es equivalente a:.Equals () en primitivo
Aquí necesitamos ver qué es el método Equals (), llamamos a Equals con una variable de tipo corto. Entonces hay tres posibilidades:
El primer tipo no es el caso aquí ya que el número de argumentos es diferente al que llamamos con un solo argumento de tipo int. El tercero también se elimina como se mencionó anteriormente, no es posible la conversión implícita de int a short. Así que aquí
Equals(object)se llama el segundo tipo de . Elshort.Equals(object)es:Entonces, aquí se probó la condición
z is shortque es falsa ya que z es un int, por lo que devuelve falsoAquí hay un artículo detallado de Eric Lippert
fuente