visual mayusculas importar ejemplos diferente comparar cadenas c# string comparison

mayusculas - string.compare c#



Diferencias en los métodos de comparación de cadenas en C# (11)

Comparar la cadena en C # es bastante simple. De hecho hay varias formas de hacerlo. He enumerado algunos en el bloque de abajo. De lo que tengo curiosidad son las diferencias entre ellas y cuándo debe usarse una sobre las otras ¿Debe uno evitarse a toda costa? ¿Hay más que no he enumerado?

string testString = "Test"; string anotherString = "Another"; if (testString.CompareTo(anotherString) == 0) {} if (testString.Equals(anotherString)) {} if (testString == anotherString) {}

(Nota: estoy buscando igualdad en este ejemplo, no menor o mayor que, pero siéntase libre de comentar sobre eso también)


Aquí están las reglas de cómo funcionan estas funciones:

stringValue.CompareTo(otherStringValue)

  1. null viene antes de una cadena
  2. utiliza CultureInfo.CurrentCulture.CompareInfo.Compare , lo que significa que usará una comparación dependiente de la cultura. Esto podría significar que ß se comparará igual a SS en Alemania, o similar

stringValue.Equals(otherStringValue)

  1. null no se considera igual a nada
  2. a menos que especifique una opción StringComparison , usará lo que parece una verificación de igualdad ordinal directa, es decir, ß no es lo mismo que SS , en cualquier idioma o cultura

stringValue == otherStringValue

  1. No es lo mismo que stringValue.Equals() .
  2. El operador == llama al método estático Equals(string a, string b) (que a su vez va a un EqualsHelper interno para hacer la comparación).
  3. Llamar a .Equals() en una cadena null obtiene una excepción de referencia null , mientras que en == no.

Object.ReferenceEquals(stringValue, otherStringValue)

Solo verifica que las referencias sean iguales, es decir, no son solo dos cadenas con el mismo contenido, sino que se está comparando un objeto de cadena consigo mismo.

Tenga en cuenta que con las opciones anteriores que utilizan el método de llamadas, hay sobrecargas con más opciones para especificar cómo comparar.

Mi consejo si solo desea verificar la igualdad es decidir si desea utilizar una comparación dependiente de la cultura o no, y luego usar .Equals o .Equals , dependiendo de la elección.


Como dijo Ed , CompareTo se utiliza para la clasificación.

Sin embargo, hay una diferencia entre .Equals y ==.

== resuelve esencialmente el siguiente código:

if(object.ReferenceEquals(left, null) && object.ReferenceEquals(right, null)) return true; if(object.ReferenceEquals(left, null)) return right.Equals(left); return left.Equals(right);

La razón simple es la siguiente lanzará una excepción:

string a = null; string b = "foo"; bool equal = a.Equals(b);

Y lo siguiente no lo hará:

string a = null; string b = "foo"; bool equal = a == b;


Desde MSDN:

"El método CompareTo fue diseñado principalmente para su uso en operaciones de ordenación o alfabetización. No debe usarse cuando el propósito principal de la llamada al método es determinar si dos cadenas son equivalentes. Para determinar si dos cadenas son equivalentes, llame al método Equals. "

Sugieren utilizar .Equals lugar de .CompareTo cuando se busca únicamente la igualdad. No estoy seguro de si hay una diferencia entre .Equals y == para la clase de string . A veces .Equals o Object.ReferenceEquals lugar de == para mis propias clases en caso de que alguien venga más tarde y redefine el operador == para esa clase.


En los formularios que enumeró aquí, no hay mucha diferencia entre los dos. CompareTo termina llamando a un método CompareInfo que hace una comparación usando la cultura actual; Equals es llamado por el operador == .

Si consideras sobrecargas, entonces las cosas se ponen diferentes. Compare y == solo puede usar la cultura actual para comparar una cadena. Equals y String.Compare pueden tomar un argumento de enumeración StringComparison que le permite especificar String.Compare no hacen StringComparison cultura o que no hacen caso de las mayúsculas. Solo String.Compare permite especificar un CultureInfo y realizar comparaciones utilizando un cultura diferente al de la cultura predeterminada.

Debido a su versatilidad, encuentro que uso String.Compare más que cualquier otro método de comparación; me permite especificar exactamente lo que quiero.


No es que el rendimiento generalmente importe con el 99% de las veces que necesita hacer esto, pero si tuviera que hacer esto en un bucle varios millones de veces, le sugeriría encarecidamente que use .Equals o == porque tan pronto como encuentre un personaje eso no coincide, hace que todo salga como falso, pero si usa la función CompareTo, tendrá que averiguar qué personaje es menor que el otro, lo que lleva a un tiempo de rendimiento ligeramente peor.

Si su aplicación se ejecutará en diferentes países, le recomiendo que revise las implicaciones de CultureInfo y posiblemente use .Equals. Ya que solo escribo aplicaciones para los EE. UU. (Y no me importa si no funciona correctamente por alguien), siempre uso ==.


Puede encontrar una buena explicación y prácticas sobre los problemas de comparación de cadenas en el artículo Nuevas recomendaciones para usar cadenas en Microsoft .NET 2.0 y también en Mejores prácticas para usar cadenas en .NET Framework .

Cada uno de los métodos mencionados (y otros) tiene un propósito particular. La diferencia clave entre ellos es qué tipo de StringComparison Enumeration están utilizando de forma predeterminada. Hay varias opciones:

  • Cultura actual
  • CurrentCultureIgnoreCase
  • Cultura invariante
  • InvariantCultureIgnoreCase
  • Ordinal
  • OrdinalIgnoreCase

Cada uno de los tipos de comparación anteriores apunta a diferentes casos de uso:

  • Ordinal
    • Identificadores internos que distinguen entre mayúsculas y minúsculas
    • Identificadores sensibles a mayúsculas y minúsculas en estándares como XML y HTTP
    • Configuración relacionada con la seguridad que distingue entre mayúsculas y minúsculas
  • OrdinalIgnoreCase
    • Identificadores internos insensibles a mayúsculas
    • Identificadores que no distinguen entre mayúsculas y minúsculas en estándares como XML y HTTP
    • Rutas de archivos (en Microsoft Windows)
    • Claves de registro / valores
    • Variables de entorno
    • Identificadores de recursos (manejar nombres, por ejemplo)
    • Configuración relacionada con la seguridad que no distingue entre mayúsculas y minúsculas
  • InvariantCulture o InvariantCultureIgnoreCase
    • Algunos datos persistentes de relevancia lingüística.
    • Visualización de datos lingüísticos que requieren un orden de clasificación fijo.
  • CurrentCulture o CurrentCultureIgnoreCase
    • Datos mostrados al usuario.
    • La mayoría de la entrada del usuario

Tenga en cuenta que StringComparison Enumeration , así como las sobrecargas para los métodos de comparación de cadenas, existe desde .NET 2.0.

Método String.CompareTo (String)

Es de hecho el tipo de implementación segura del método IComparable.CompareTo . Interpretación por defecto: CurrentCulture.

Uso:

El método CompareTo fue diseñado principalmente para su uso en operaciones de ordenación o alfabetización

Así

Implementar la interfaz de IComparable necesariamente usará este método

String.Compare Method

Un miembro estático de String Class que tiene muchas sobrecargas. Interpretación por defecto: CurrentCulture.

Siempre que sea posible, debe llamar a una sobrecarga del método de comparación que incluye un parámetro StringComparison.

Método String.Equals

Anulado de la clase Objeto y sobrecargado para seguridad de tipo. Interpretación por defecto: ordinal. Darse cuenta de:

Los métodos de igualdad de la clase String incluyen los iguales estáticos , el operador estático == y el método de instancia iguales .

Clase StringComparer

También hay otra forma de lidiar con las comparaciones de cadenas, especialmente con la ordenación:

Puede usar la clase StringComparer para crear una comparación específica de tipo para ordenar los elementos en una colección genérica. Clases como Hashtable, Dictionary, SortedList y SortedList usan la clase StringComparer para propósitos de clasificación.


Si alguna vez siente curiosidad por las diferencias en los métodos BCL, Reflector es su amigo :-)

Sigo estas pautas:

Coincidencia exacta: EDITAR: Anteriormente siempre usaba el operador == sobre el principio de que dentro de Igual a (cadena, cadena) el operador == se usa para comparar las referencias de los objetos, pero parece que strA.Equals (strB) sigue siendo 1-11% más rápido en general que string.Equals (strA, strB), strA == strB y string.CompareOrdinal (strA, strB). Probé en bucle con un StopWatch en valores de cadena internados / no internados, con longitudes de cadena iguales / diferentes, y tamaños variables (1B a 5MB).

strA.Equals(strB)

Coincidencia legible por humanos (culturas occidentales, sin distinción de mayúsculas y minúsculas):

string.Compare(strA, strB, StringComparison.OrdinalIgnoreCase) == 0

Coincidencia legible por humanos (Todas las otras culturas, caso insensible / acento / kana / etc definido por CultureInfo):

string.Compare(strA, strB, myCultureInfo) == 0

Coincidencia legible por humanos con reglas personalizadas (Todas las demás culturas):

CompareOptions compareOptions = CompareOptions.IgnoreCase | CompareOptions.IgnoreWidth | CompareOptions.IgnoreNonSpace; string.Compare(strA, strB, CultureInfo.CurrentCulture, compareOptions) == 0


Una gran diferencia a tener en cuenta es .Equals () lanzará una excepción si la primera cadena es nula, mientras que == no lo hará.

string s = null; string a = "a"; //Throws {"Object reference not set to an instance of an object."} if (s.Equals(a)) Console.WriteLine("s is equal to a"); //no Exception if(s==a) Console.WriteLine("s is equal to a");


Usar .Equals también es mucho más fácil de leer .


con .Equals, también obtienes las opciones StringComparison. Muy útil para ignorar el caso y otras cosas.

por cierto, esto se evaluará como falso

string a = "myString"; string b = "myString"; return a==b

Como == compara los valores de a y b (que son punteros), esto solo se evaluará como verdadero si los punteros apuntan al mismo objeto en la memoria. .Equals desreferencia los punteros y compara los valores almacenados en los punteros. a.Las ecuaciones (b) serían verdaderas aquí.

y si cambias b por:

b = "MYSTRING";

entonces a.Equals (b) es falso, pero

a.Equals(b, StringComparison.OrdinalIgnoreCase)

seria verdad

a.CompareTo (b) llama a la función CompareTo de la cadena que compara los valores en los punteros y devuelve <0 si el valor almacenado en a es menor que el valor almacenado en b, devuelve 0 si a.Equals (b) es verdadero, y > 0 de lo contrario. Sin embargo, esto distingue entre mayúsculas y minúsculas, creo que hay opciones para que ComparTo ignore mayúsculas y demás, pero no tengo tiempo para mirar ahora. Como otros ya han dicho, esto se haría para la clasificación. La comparación de la igualdad de esta manera daría lugar a gastos generales innecesarios.

Estoy seguro de que estoy dejando cosas fuera, pero creo que esta información debería ser suficiente para comenzar a experimentar si necesitas más detalles.


  • s1.CompareTo (s2): NO usar si el propósito principal es determinar si dos cadenas son equivalentes
  • s1 == s2: no se puede ignorar el caso
  • s1.Equals (s2, StringComparison): emite NullReferenceException si s1 es nulo
  • String.Equals (s2, StringComparison): ¡ mediante el proceso de eliminación, este método estático es el GANADOR (asumiendo un caso de uso típico para determinar si dos cadenas son equivalentes)!