c# .net equals

equals contains c#



C#diferencia entre== y igual() (16)

Tengo una condición en una aplicación de Silverlight que compara 2 cadenas, por alguna razón, cuando uso == devuelve falso mientras que .Equals() devuelve verdadero .

Aquí está el código:

if (((ListBoxItem)lstBaseMenu.SelectedItem).Content.Equals("Energy Attack")) { // Execute code } if (((ListBoxItem)lstBaseMenu.SelectedItem).Content == "Energy Attack") { // Execute code }

¿Alguna razón de por qué esto está sucediendo?


Añadiendo un punto más a la respuesta.

.EqualsTo() método .EqualsTo() le brinda la posibilidad de compararlo con la cultura y las mayúsculas y minúsculas.



Cuando se compara una referencia de objeto con una cadena (incluso si la referencia de objeto se refiere a una cadena), se ignora el comportamiento especial del operador == específico de la clase de cadena.

Normalmente (cuando no se trata de cadenas, es decir), Equals compara valores , mientras que == compara referencias de objetos . Si los dos objetos que está comparando se refieren a la misma instancia exacta de un objeto, ambos devolverán el valor verdadero, pero si uno tiene el mismo contenido y proviene de una fuente diferente (es una instancia separada con los mismos datos), solo los iguales volver verdadero Sin embargo, como se señaló en los comentarios, la cadena es un caso especial porque reemplaza al operador == modo que cuando se trata únicamente de referencias de cadena (y no de referencias de objeto), solo se comparan los valores incluso si son instancias separadas. El siguiente código ilustra las diferencias sutiles en los comportamientos:

string s1 = "test"; string s2 = "test"; string s3 = "test1".Substring(0, 4); object s4 = s3; Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2)); Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3)); Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4));

La salida es:

True True True False True True False False True


Cuando se usa == en una expresión de tipo object , se resolverá en System.Object.ReferenceEquals .

Equals es solo un método virtual y se comporta como tal, por lo que se usará la versión anulada (que, para el tipo de string compara el contenido).


Debido a que la versión estática del método .Equal no se mencionó hasta ahora, me gustaría agregar esto aquí para resumir y comparar las 3 variaciones.

MyString.Equals("Somestring")) //Method 1 MyString == "Somestring" //Method 2 String.Equals("Somestring", MyString); //Method 3 (static String.Equals method) - better

donde MyString es una variable que viene de algún otro lugar en el código.

Información de fondo y para resumir:

En Java, usar == para comparar cadenas no debe usarse. Menciono esto en caso de que necesite usar ambos idiomas y también para hacerle saber que usar == también se puede reemplazar con algo mejor en C #.

En C # no hay una diferencia práctica para comparar cadenas utilizando el Método 1 o el Método 2 siempre que ambos sean de tipo cadena. Sin embargo, si uno es nulo, uno es de otro tipo (como un entero), o uno representa un objeto que tiene una referencia diferente, entonces, como muestra la pregunta inicial, puede experimentar que comparar el contenido para la igualdad puede no devolver lo que tu esperas.

Solución sugerida:

Debido a que usar == no es exactamente lo mismo que usar .Equals al comparar cosas, puedes usar el método String.Equals estático . De esta manera, si los dos lados no son del mismo tipo, seguirá comparando el contenido y si uno es nulo, evitará la excepción.

bool areEqual = String.Equals("Somestring", MyString);

Es un poco más para escribir, pero en mi opinión, más seguro de usar.

Aquí hay alguna información copiada de Microsoft:

public static bool Equals (string a, string b);

Parámetros

a cadena

La primera cadena para comparar, o null .

cadena de b

La segunda cadena para comparar, o null .

Devuelve Boolean

true si el valor de a es el mismo que el valor de b ; de lo contrario, false . Si a y b son null , el método devuelve true .


El == token en C # se usa para dos operadores de verificación de igualdad diferentes. Cuando el compilador se encuentra con ese token, verificará si alguno de los tipos que se comparan ha implementado una sobrecarga de operador de igualdad para los tipos de combinación específicos que se comparan (*), o para una combinación de tipos a los que se pueden convertir ambos tipos. Si el compilador encuentra tal sobrecarga, la usará. De lo contrario, si los dos tipos son tipos de referencia y no son clases no relacionadas (o bien puede ser una interfaz o clases relacionadas), el compilador considerará == como un operador de comparación de referencia. Si no se aplica ninguna condición, la compilación fallará.

Tenga en cuenta que algunos otros idiomas usan tokens separados para los dos operadores de verificación de igualdad. En VB.NET, por ejemplo, el token = se usa dentro de expresiones únicamente para el operador de verificación de igualdad sobrecargable, y se usa como un operador de prueba de referencia o de prueba nula. El uso de = en un tipo que no anule al operador de verificación de igualdad fallará, al igual que el intento de usar Is para cualquier otro propósito que no sea probar la igualdad o nulidad de referencia.

(*) Los tipos generalmente solo sobrecargan la igualdad para la comparación con ellos mismos, pero puede ser útil para los tipos sobrecargar al operador de la igualdad para la comparación con otros tipos particulares; por ejemplo, int podría haber (y IMHO debería haber definido pero no definido) operadores de igualdad para compararlos con float , de modo que 16777217 no se reportaría igual a 16777216f. Tal como está, ya que no se define tal operador, C # promoverá la float int , redondeando a 16777216f antes de que el operador de verificación de igualdad lo vea; ese operador ve dos números de punto flotante iguales y los informa como iguales, sin darse cuenta del redondeo que tuvo lugar.


En primer lugar, hay una diferencia. Para numeros

> 2 == 2.0 True > 2.Equals(2.0) False

Y por cuerdas

> string x = null; > x == null True > x.Equals(null) NullReferenceException

En ambos casos, == comporta de manera más útil que .Equals


Estoy un poco confundido aquí. Si el tipo de Contenido en tiempo de ejecución es de tipo cadena, entonces tanto == como Equals deberían devolver verdadero. Sin embargo, dado que este no parece ser el caso, entonces el tipo de Contenido en tiempo de ejecución no es una cadena y llamar a Equals está haciendo una igualdad referencial y esto explica por qué falla Equals ("Energy Attack"). Sin embargo, en el segundo caso, la decisión sobre a qué operador estático == sobrecargado se debe llamar se toma en el momento de la compilación y esta decisión parece ser == (cadena, cadena). esto me sugiere que el Contenido proporciona una conversión implícita a cadena.


Hay otra dimensión a una respuesta anterior por @BlueMonkMN. La dimensión adicional es que la respuesta a la pregunta del título de @ Drahcir tal como se establece también depende de cómo llegamos al valor de la string . Para ilustrar:

string s1 = "test"; string s2 = "test"; string s3 = "test1".Substring(0, 4); object s4 = s3; string s5 = "te" + "st"; object s6 = s5; Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s2), s1 == s2, s1.Equals(s2)); Console.WriteLine("/n Case1 - A method changes the value:"); Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s3), s1 == s3, s1.Equals(s3)); Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s4), s1 == s4, s1.Equals(s4)); Console.WriteLine("/n Case2 - Having only literals allows to arrive at a literal:"); Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s5), s1 == s5, s1.Equals(s5)); Console.WriteLine("{0} {1} {2}", object.ReferenceEquals(s1, s6), s1 == s6, s1.Equals(s6));

La salida es:

True True True Case1 - A method changes the value: False True True False False True Case2 - Having only literals allows to arrive at a literal: True True True True True True


La única diferencia entre Igual y == es en la comparación de tipo de objeto. en otros casos, como los tipos de referencia y los tipos de valor, son casi los mismos (ambos son iguales a nivel de bits o ambos son igualdad de referencia).

objeto: es igual a: igualdad de bits ==: igualdad de referencia

cadena: (igual y == son lo mismo para la cadena, pero si una de la cadena cambió a objeto, el resultado de la comparación será diferente) Igual: igualdad a nivel de bits ==: igualdad a nivel de bits

Vea here para más explicación.


Por lo que yo entiendo, la respuesta es simple:

  1. == compara referencias de objetos.
  2. .Equals compara el contenido del objeto.
  3. Los tipos de datos de cadena siempre actúan como comparación de contenido.

Espero estar en lo cierto y que haya respondido a tu pregunta.


Realmente grandes respuestas y ejemplos!

Solo me gustaría añadir la diferencia fundamental entre los dos,

Los operadores como == no son polimórficos, mientras que Equals es

Teniendo en cuenta ese concepto, si resuelve algún ejemplo (mirando el tipo de referencia de la mano izquierda y la mano derecha, y comprobando / sabiendo si el tipo en realidad tiene == operador sobrecargado e Igualdad anulada), está seguro de obtener la respuesta correcta .


Yo agregaría que si lanzas tu objeto a una cadena, entonces funcionará correctamente. Es por esto que el compilador le dará una advertencia diciendo:

Posible comparación de referencia involuntaria; para obtener una comparación de valores, coloque el lado izquierdo para escribir ''cadena''


== y .Equals dependen del comportamiento definido en el tipo real y del tipo real en el sitio de la llamada. Ambos son solo métodos / operadores que pueden ser anulados en cualquier tipo y dado el comportamiento que el autor desee. En mi experiencia, creo que es común que las personas implementen .Equals en un objeto, pero se .Equals a implementar operator == . Esto significa que .Equals realmente medirá la igualdad de los valores mientras que == medirá si son o no la misma referencia.

Cuando trabajo con un nuevo tipo cuya definición está en flujo o escribiendo algoritmos genéricos, encuentro que la mejor práctica es la siguiente

  • Si quiero comparar referencias en C #, uso Object.ReferenceEquals directamente (no es necesario en el caso genérico)
  • Si quiero comparar valores, uso EqualityComparer<T>.Default

En algunos casos, cuando siento que el uso de == es ambiguo, Object.Reference explícitamente Object.Reference es igual en el código para eliminar la ambigüedad.

Eric Lippert recientemente hizo una publicación en el blog sobre el tema de por qué hay 2 métodos de igualdad en el CLR. Vale la pena leer


==

El operador == se puede usar para comparar dos variables de cualquier tipo, y simplemente compara los bits .

int a = 3; byte b = 3; if (a == b) { // true }

Nota: hay más ceros en el lado izquierdo de la int, pero no nos importa eso aquí.

int a (00000011) == byte b (00000011)

Recuerde que el operador == solo se preocupa por el patrón de los bits en la variable.

Use == Si dos referencias (primitivas) se refieren al mismo objeto en el montón.

Las reglas son las mismas si la variable es una referencia o una primitiva.

Foo a = new Foo(); Foo b = new Foo(); Foo c = a; if (a == b) { // false } if (a == c) { // true } if (b == c) { // false }

a == c es verdadero a == b es falso

el patrón de bits es el mismo para a y c, por lo que son iguales usando ==.

Igual():

Utilice el método equals () para ver si dos objetos diferentes son iguales .

Como dos objetos String diferentes que representan a los personajes en "Jane"


== Operador 1. Si los operandos son tipos de valor y sus valores son iguales, devuelve verdadero o falso. 2. Si los operandos son tipos de referencia con excepción de la cadena y ambos se refieren al mismo objeto, devuelve verdadero si no, falso. 3. Si los operandos son de tipo cadena y sus valores son iguales, devuelve verdadero o falso.

.Equals 1. Si los operandos son Tipos de referencia, realiza Igualdad de referencia, es decir, si ambos se refieren al mismo objeto, devuelve verdadero si no, falso. 2. Si los operandos son tipos de valor, a diferencia del operador ==, primero verifica su tipo y si sus tipos son los mismos, el operador == devuelve falso.