visual tipos studio que predefinidas librerias ejemplos datos conversion clases c# compare

studio - tipos de librerias en c#



¿Cuál es la diferencia entre== e Igual() para las primitivas en C#? (9)

Respuesta corta:

La igualdad es complicada.

Respuesta detallada:

Los tipos primitivos anulan el object.Equals(object) base. object.Equals(object) y devuelven verdadero si el object caja es del mismo tipo y valor. (Tenga en cuenta que también funcionará para tipos anulables; los tipos nulos que no aceptan nulos siempre se ajustan a una instancia del tipo subyacente).

Como newAge es un short , su método Equals(object) solo devuelve true si pasa un short en caja con el mismo valor. Estás pasando un int encuadrado, por lo que devuelve falso.

Por el contrario, el operador == se define como tomar dos int s (o short s o long s).
Cuando lo llames con un int y un short , el compilador convertirá implícitamente el short a int y comparará los int resultantes por valor.

Otras formas de hacerlo funcionar

Los tipos primitivos también tienen su propio método Equals() que acepta el mismo tipo.
Si escribe age.Equals(newAge) , el compilador seleccionará int.Equals(int) como la mejor sobrecarga y convertirá implícitamente short a int . Luego devolverá true , ya que este método simplemente compara los int s directamente.

short también tiene un short.Equals(short) , pero int no se puede convertir implícitamente en short , por lo que no lo está llamando.

Podría forzarlo a llamar a este método con un molde:

Console.WriteLine(newAge.Equals((short)age)); // true

Esto llamará short.Equals(short) directamente, sin boxeo. Si la age es mayor que 32767, arrojará una excepción de desbordamiento.

También puede llamar a la short.Equals(object) , pero pasar explícitamente un objeto en caja para que tenga el mismo tipo:

Console.WriteLine(newAge.Equals((object)(short)age)); // true

Al igual que la alternativa anterior, esto arrojará un desbordamiento si no cabe en un short . A diferencia de la solución anterior, encajonará el short en un objeto, perdiendo tiempo y memoria.

Código fuente:

Aquí hay ambos métodos Equals() del código fuente actual:

public override bool Equals(Object obj) { if (!(obj is Int16)) { return false; } return m_value == ((Int16)obj).m_value; } public bool Equals(Int16 obj) { return m_value == obj; }

Otras lecturas:

Ver blog.coverity.com/2014/01/13/inconsistent-equality .

Considera este código:

int age = 25; short newAge = 25; Console.WriteLine(age == newAge);  //true Console.WriteLine(newAge.Equals(age)); //false Console.ReadLine();

Tanto int como short son tipos primitivos, pero una comparación con == devuelve true y una comparación con Equals devuelve false.

¿Por qué?


Cuando pasa int a short ''s Iguala pasa object :

Entonces este pseudocódigo corre:

return obj is short && this == (short)obj;


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ícito. Si el compilador puede hacer que todos los argumentos satisfagan a sus operadores y métodos agregando conversiones implícitas, lo hará sin queja, aunque en algunos casos (¡especialmente con pruebas de igualdad!) Los resultados pueden ser sorprendentes.

Además, cada tipo de valor, como int o short 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 en su tipo correspondiente de objeto, pero los diferentes tipos de objetos no son implícitamente convertibles entre sí.

Si uno usa el operador == para comparar un short y un int , el short se convertirá implícitamente en un int . Si su valor numérico fue igual al de int , el int al que se convirtió será igual al int con el que se compara. Sin embargo, si se intenta utilizar el método Equals en el corto para compararlo con un int , la única conversión implícita que satisfaría una sobrecarga del método Equals sería la conversión al tipo de objeto correspondiente a int . Cuando se le pregunta al short si coincide con el objeto pasado, observará que el objeto en cuestión es un int lugar de un short y, por lo tanto, concluye que posiblemente no sea igual.

En general, aunque el compilador no se quejará de eso, uno debe evitar comparar cosas que no son del mismo tipo; si uno está interesado en si la conversión de cosas a una forma común daría el mismo resultado, uno debería realizar dicha conversión explícitamente. Considera, por ejemplo,

int i = 16777217; float f = 16777216.0f; Console.WriteLine("{0}", i==f);

Hay tres formas en que uno puede querer comparar un int con un float . Uno puede querer saber:

  1. ¿El valor float más cercano posible al int coincide con el float ?
  2. ¿La parte entera del float coincide con el int ?
  3. Los valores int y float representan el mismo valor numérico.

Si uno intenta comparar un int y float directamente, el código compilado responderá a la primera pregunta; si eso es lo que el programador pretendió, sin embargo, no será nada obvio. Cambiar la comparación a (float)i == f dejaría en claro que el primer significado fue intencionado, o (double)i == (double)f haría que el código responda la tercera pregunta (y aclare que eso fue lo que destinado a).

(*) Incluso si la especificación de C # se refiere a un valor de tipo p. Ej. System.Int32 como un objeto de tipo System.Int32 , dicha visión se contradice con el requisito de que un código se ejecute en una plataforma cuya especificación se refiere a valores y objetos que habitan diferentes universos. Además, si T es un tipo de referencia, x es un T , entonces una referencia de tipo T debería poder referirse a x . Por lo tanto, si una variable v de tipo Int32 contiene un Object , una referencia de tipo Object debería poder contener una referencia a v o su contenido. De hecho, una referencia de tipo Object podría apuntar a un objeto que contiene datos copiados de v , pero no a v ni a sí mismo ni a su contenido. Eso sugeriría que ni v ni su contenido son realmente un Object .


Lo que necesita darse cuenta es que hacer == siempre terminará llamando a un método. La pregunta es si llamar == e Equals termina haciendo llamadas / haciendo las mismas cosas.

Con tipos de referencia, == siempre verificará primero si las referencias son las mismas ( Object.ReferenceEquals ). Equals por otro lado, puede anularse y puede verificar si algunos valores son iguales.

EDITAR: para responder svick y agregar el comentario de SLaks, aquí hay un código IL

int i1 = 0x22; // ldc.i4.s ie pushes an int32 on the stack int i2 = 0x33; // ldc.i4.s short s1 = 0x11; // ldc.i4.s (same as for int32) short s2 = 0x22; // ldc.i4.s s1 == i1 // ceq i1 == s1 // ceq i1 == i2 // ceq s1 == s2 // ceq // no difference between int and short for those 4 cases, // anyway the shorts are pushed as integers. i1.Equals(i2) // calls System.Int32.Equals s1.Equals(s2) // calls System.Int16.Equals i1.Equals(s1) // calls System.Int32.Equals: s1 is considered as an integer // - again it was pushed as such on the stack) s1.Equals(i1) // boxes the int32 then calls System.Int16.Equals // - int16 has 2 Equals methods: one for in16 and one for Object. // Casting an int32 into an int16 is not safe, so the Object overload // must be used instead.



Porque no hay sobrecarga para short.Equals que aceptan un int . Por lo tanto, esto se llama:

public override bool Equals(object obj) { return obj is short && this == (short)obj; }

obj no es un short ... por lo tanto, es falso.


== 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 habrá un tipo de conversión hecho e Equals también se usa para la comprobación es igual a la condición, pero en este caso los tipos de datos deben ser iguales. N Equals es un método, no un operador.

A continuación se muestra un pequeño ejemplo tomado del que usted proporcionó y esto aclarará la diferencia en pocas palabras.

int x=1; short y=1; x==y;//true y.Equals(x);//false

en el ejemplo anterior, X e Y tienen los mismos valores, es decir 1, y cuando usamos == , devolverá verdadero, como en el caso de == , el compilador convertirá el tipo abreviado en int y se dará el resultado.

y cuando usamos Equals , la comparación se hace, pero el tipo de conversión no se realiza por el compilador, por lo que se devuelve falso.

Chicos, por favor, háganme saber si estoy equivocado.


== En primitivo

Console.WriteLine(age == newAge); // true

En la comparación primitiva, el operador == se comporta de manera bastante obvia, en C # hay muchas == sobrecarga del operador disponible.

  • cadena == cadena
  • int == int
  • uint == uint
  • largo == largo
  • mucho mas

Entonces en este caso no hay conversión implícita de int a short pero short to int es posible. Entonces, newAge se convierte en int y se produce una comparación que devuelve true ya que ambos tienen el mismo valor. Entonces es equivalente a:

Console.WriteLine(age == (int)newAge); // true

.Equals () en Primitive

Console.WriteLine(newAge.Equals(age)); //false

Aquí tenemos que ver qué método es Equals (), llamamos a Equals con una variable de tipo abreviada. Entonces hay tres posibilidades:

  • Igual (objeto, objeto) // método estático del objeto
  • Igual (objeto) // método virtual del objeto
  • Igual (corto) // Implementa EQuables.Equals (corto)

El primer tipo no es el caso aquí ya que el número de argumentos es diferente que llamamos con solo un argumento de tipo int. En tercer lugar también se elimina como se mencionó anteriormente la conversión implícita de int a corto no es posible. Entonces aquí se llama el segundo tipo de Equals(object) . El short.Equals(object) es:

bool Equals(object z) { return z is short && (short)z == this; }

Así que aquí la condición se puso a prueba z is short que es falsa, ya que z es una int, por lo que devuelve false.

Aquí está el artículo detallado de Eric Lippert


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 que los valores son los mismos.

Por favor, no te confundas con ReferenceEqual

Referencia igual ()
Sintaxis: bool estático público ReferenceEquals ()
Determina si la instancia de los objetos especificados es de la misma instancia