strings stringcomparison not found ejemplo comparestring comparar c# string equals

c# - stringcomparison - ¿Por qué usarías String.Equals over==?



string.equals c# (8)

Esta pregunta ya tiene una respuesta aquí:

Hace poco recibí una gran base de código y noté que todas las comparaciones de cadenas se hacen usando String.Equals() lugar de ==

¿Cuál es la razón de esto, crees?


Acabo de golpearme la cabeza contra un muro tratando de resolver un error porque leí esta página y llegué a la conclusión de que no había una diferencia significativa cuando en la práctica lo hay, así que publicaré este enlace aquí en caso de que alguien más encuentre que obtienen resultados diferentes. fuera de == y es igual.

Objeto == la igualdad falla, pero .Equals tiene éxito. ¿Esto tiene sentido?

string a = "x"; string b = new String(new []{''x''}); Console.WriteLine("x == x " + (a == b));//True Console.WriteLine("object x == x " + ((object)a == (object)b));//False Console.WriteLine("x equals x " + (a.Equals(b)));//True Console.WriteLine("object x equals x " + (((object)a).Equals((object)b)));//True


Ambos métodos hacen la misma funcionalidad - para comparar valores . Como está escrito en MSDN:

Pero si una de sus instancias de cadena es nula, estos métodos funcionan de manera diferente:

string x = null; string y = "qq"; if (x == y) // returns false MessageBox.Show("true"); else MessageBox.Show("false"); if (x.Equals(y)) // returns System.NullReferenceException: Object reference not set to an instance of an object. - because x is null !!! MessageBox.Show("true"); else MessageBox.Show("false");


Es muy probable que una gran parte de la base de desarrolladores provenga de un fondo de Java donde el uso de == para comparar cadenas es incorrecto y no funciona.

En C # no hay diferencia (práctica) (para cadenas) siempre que se escriban como cadena.

Si se escriben como object o T , vea otras respuestas aquí que hablan de métodos genéricos o sobrecarga de operadores, ya que definitivamente desea utilizar el método de Equals.


Hay una diferencia sutil pero muy importante entre == y los métodos String.Equals:

class Program { static void Main(string[] args) { CheckEquality("a", "a"); Console.WriteLine("----------"); CheckEquality("a", "ba".Substring(1)); } static void CheckEquality<T>(T value1, T value2) where T : class { Console.WriteLine("value1: {0}", value1); Console.WriteLine("value2: {0}", value2); Console.WriteLine("value1 == value2: {0}", value1 == value2); Console.WriteLine("value1.Equals(value2): {0}", value1.Equals(value2)); if (typeof(T).IsEquivalentTo(typeof(string))) { string string1 = (string)(object)value1; string string2 = (string)(object)value2; Console.WriteLine("string1 == string2: {0}", string1 == string2); } } }

Produce esta salida:

value1: a value2: a value1 == value2: True value1.Equals(value2): True string1 == string2: True ---------- value1: a value2: a value1 == value2: False value1.Equals(value2): True string1 == string2: True

Puede ver que el operador == devuelve falso a dos cadenas obviamente iguales. ¿Por qué? Debido a que el operador == en uso en el método genérico se resuelve para ser el método op_equal definido por System.Object (la única garantía de T que el método tiene en el momento de la compilación), lo que significa que es la igualdad de referencia en lugar de la igualdad de valor.

Cuando tiene dos valores escritos como System.String explícitamente, entonces == tiene una semántica de igualdad de valores porque el compilador resuelve el == a System.String.op_equal en lugar de System.Object.op_equal.

Así que para jugar con seguridad, casi siempre uso String.Equals en lugar de eso, siempre obtengo la semántica de igualdad de valores que quiero.

Y para evitar NullReferenceExceptions si uno de los valores es nulo, siempre uso el método String.Equals estático :

bool true = String.Equals("a", "ba".Substring(1));


Hay una reseña sobre dotnetperls.com/string-equals que podría ser interesante, con algunas citas de Jon Skeet. Parece que el uso es más o menos el mismo.

Jon Skeet afirma que el rendimiento de la instancia Igual "es ligeramente mejor cuando las cadenas son cortas, ya que las cuerdas aumentan en longitud, esa diferencia se vuelve completamente insignificante".


Quiero añadir que hay otra diferencia. Está relacionado con lo que Andrew publica.

También está relacionado con un error MUY molesto para encontrar errores en nuestro software. Vea el siguiente ejemplo simplificado (también omití la comprobación nula).

public const int SPECIAL_NUMBER = 213; public bool IsSpecialNumberEntered(string numberTextBoxTextValue) { return numberTextBoxTextValue.Equals(SPECIAL_NUMBER) }

Esto compilará y siempre devolverá false . Mientras que lo siguiente dará un error de compilación:

public const int SPECIAL_NUMBER = 213; public bool IsSpecialNumberEntered(string numberTextBoxTextValue) { return (numberTextBoxTextValue == SPECIAL_NUMBER); }

Hemos tenido que resolver un problema similar en el que alguien comparaba enumeraciones de tipos diferentes utilizando Equals . Va a leer este MUCHAS veces antes de darse cuenta de que es la causa del error. Especialmente si la definición de SPECIAL_NUMBER no está cerca del área problemática.

Por eso estoy realmente en contra del uso de Equals en situaciones en las que no es necesario. Se pierde un poco de seguridad de tipo.


String.Equals ofrece sobrecargas para manejar String.Equals y comparaciones String.Equals cultura. Si su código no hace uso de estos, los desarrolladores solo pueden usarse para Java, donde (como dice Matthew), debe usar el método .Equals para hacer comparaciones de contenido.


Hay una diferencia práctica entre string.Equals y ==

bool result = false; object obj = "String"; string str2 = "String"; string str3 = typeof(string).Name; string str4 = "String"; object obj2 = str3; // Comparision between object obj and string str2 -- Com 1 result = string.Equals(obj, str2);// true result = String.ReferenceEquals(obj, str2); // true result = (obj == str2);// true // Comparision between object obj and string str3 -- Com 2 result = string.Equals(obj, str3);// true result = String.ReferenceEquals(obj, str3); // false result = (obj == str3);// false // Comparision between object obj and string str4 -- Com 3 result = string.Equals(obj, str4);// true result = String.ReferenceEquals(obj, str4); // true result = (obj == str4);// true // Comparision between string str2 and string str3 -- Com 4 result = string.Equals(str2, str3);// true result = String.ReferenceEquals(str2, str3); // false result = (str2 == str3);// true // Comparision between string str2 and string str4 -- Com 5 result = string.Equals(str2, str4);// true result = String.ReferenceEquals(str2, str4); // true result = (str2 == str4);// true // Comparision between string str3 and string str4 -- Com 6 result = string.Equals(str3, str4);// true result = String.ReferenceEquals(str3, str4); // false result = (str3 == str4);// true // Comparision between object obj and object obj2 -- Com 7 result = String.Equals(obj, obj2);// true result = String.ReferenceEquals(obj, obj2); // false result = (obj == obj2);// false

Añadiendo reloj

obj "String" {1#} object {string} str2 "String" {1#} string str3 "String" {5#} string str4 "String" {1#} string obj2 "String" {5#} object {string}

Ahora mira {1#} y {5#}

obj2 referencias obj , str4 , str4 y obj2 son iguales.

obj y obj2 son object type y otros son string type

Conclusion :

  1. com1 : result = (obj == str2); // true
    • compara el object y la string para que realice una verificación de igualdad de referencia
    • obj y str2 apuntan a la misma referencia por lo que el resultado es verdadero
  2. com2 : result = (obj == str3); // false
    • compara el object y la string para que realice una verificación de igualdad de referencia
    • obj y str3 apuntan a las diferentes referencias por lo que el resultado es falso
  3. com3 : result = (obj == str4); // true
    • compara el object y la string para que realice una verificación de igualdad de referencia
    • obj y str4 apuntan a la misma referencia por lo que el resultado es verdadero
  4. com4 : result = (str2 == str3); // true
    • compara la string y la string por lo que realiza una verificación de valor de cadena
    • str2 y str3 son "String" por lo que el resultado es verdadero
  5. com5 : result = (str2 == str4); // true
    • compara la string y la string por lo que realiza una verificación de valor de cadena
    • str2 y str4 son "String", por lo que el resultado es verdadero
  6. com6 : result = (str3 == str4); // true
    • compara la string y la string por lo que realiza una verificación de valor de cadena
    • str3 y str4 son ambos "String" por lo que el resultado es verdadero
  7. com7 : result = (obj == obj2); // false: compara el object y el object por lo que realiza una verificación de igualdad de referencia: obj y obj2 apuntan a las diferentes referencias, por lo que el resultado es falso