¿Cuál es generalmente mejor usar – StringComparison.OrdinalIgnoreCase o StringComparison.InvariantCultureIgnoreCase?

Tengo un código como este:

If key.Equals("search", StringComparison.OrdinalIgnoreCase) Then DoSomething() End If 

No me importa el caso. ¿Debo usar OrdinalIgnoreCase , InvariantCultureIgnoreCase o CurrentCultureIgnoreCase ?

De ” Nuevas recomendaciones para utilizar cadenas en Microsoft .NET 2.0 ” de MSDN

Resumen: los propietarios de los códigos que antes usaban InvariantCulture para la comparación de cadenas, la envoltura y la clasificación deberían considerar seriamente utilizar un nuevo conjunto de sobrecargas String en Microsoft .NET 2.0. Específicamente, los datos que están diseñados para ser culturalmente independientes y lingüísticamente irrelevantes deben comenzar a especificar sobrecargas usando los miembros StringComparison.Ordinal o StringComparison.OrdinalIgnoreCase de la nueva enumeración de StringComparison. Estos hacen cumplir una comparación de byte a byte similar a strcmp que no solo evita errores de interpretación lingüística de cadenas esencialmente simbólicas, sino que proporciona un mejor rendimiento. (15 páginas impresas)

Todo depende

Comparar cadenas Unicode es difícil:

La implementación de búsquedas de cadenas Unicode y comparaciones en el software de procesamiento de textos debe tener en cuenta la presencia de puntos de código equivalentes. En ausencia de esta característica, los usuarios que buscan una determinada secuencia de puntos de código no podrían encontrar otros glifos visualmente indistinguibles que tengan una representación de punto de código diferente, pero canónicamente equivalente.

ver: http://en.wikipedia.org/wiki/Unicode_equivalence


Si está intentando comparar 2 cadenas de Unicode de una manera que no distingue entre mayúsculas y minúsculas y desea que funcione EN TODAS PARTES , tiene un problema imposible.

El ejemplo clásico es el i turco , que cuando está en mayúscula se convierte en İ (fíjate en el punto)

Por defecto, el framework .Net usualmente utiliza el CurrentCulture para funciones relacionadas con cadenas, con una excepción muy importante de .Equals que usa una .Equals ordinal (byte por byte).

Esto conduce, por diseño, a las diversas funciones de cadena que se comportan de manera diferente dependiendo de la cultura de la computadora.


No obstante, a veces queremos una comparación “de propósito general”, sin distinción de mayúsculas y minúsculas.

Por ejemplo, puede querer que su comparación de cadenas se comporte de la misma manera, sin importar en qué computadora esté instalada su aplicación.

Para lograr esto tenemos 3 opciones:

  1. Establezca la cultura explícitamente y realice una comparación insensible a mayúsculas y minúsculas utilizando las reglas de equivalencia Unicode.
  2. Establezca el cultivo en Cultura Invariante y realice una comparación insensible a mayúsculas y minúsculas utilizando reglas de equivalencia Unicode.
  3. Use OrdinalIgnoreCase que en mayúscula la cadena usando InvariantCulture y luego realice una comparación byte por byte.

Las reglas de equivalencia Unicode son complicadas, lo que significa que usar el método 1) o 2) es más costoso que OrdinalIgnoreCase . El hecho de que OrdinalIgnoreCase no realice ninguna normalización de Unicode especial significa que algunas cadenas que se representan de la misma manera en la pantalla de una computadora no se considerarán idénticas. Por ejemplo: "\u0061\u030a" y "\u00e5" ambos renderizan å. Sin embargo, en una comparación ordinal se considerará diferente.

Lo que elija en gran medida depende de la aplicación que está creando.

  • Si estuviera escribiendo una aplicación de línea de negocios que solo utilizaban los usuarios turcos, me aseguraría de usar el método 1.
  • Si solo necesitara una comparación insensible de casos “falsos” simple, por ejemplo un nombre de columna en una base de datos, que generalmente es inglés, probablemente usaría el método 3.

Microsoft tiene su conjunto de recomendaciones con pautas explícitas. Sin embargo, es realmente importante entender la noción de equivalencia Unicode antes de abordar estos problemas.

Además, tenga en cuenta que OrdinalIgnoreCase es un tipo de bestia muy especial , que está escogiendo y eligiendo un poco de una comparación ordinal con algunos aspectos mixtos lexicográficos. Esto puede ser confuso.

MSDN hace algunas recomendaciones bastante claras sobre esto: http://msdn.microsoft.com/en-us/library/ms973919.aspx

Supongo que depende de tu situación. Dado que las comparaciones ordinales en realidad están mirando los valores numéricos Unicode de los personajes, no serán la mejor opción cuando ordena alfabéticamente. Para las comparaciones de cadenas, sin embargo, ordinal sería un poco más rápido.

Depende de lo que quieras, aunque me alejaré de la cultura invariable a menos que estés muy seguro de que nunca querrás localizar el código para otros idiomas. Use CurrentCulture en su lugar.

Además, OrdinalIgnoreCase debe respetar los números, que pueden ser o no lo que usted desea.

La respuesta más simple es que, a menos que use turco, no necesita usar InvariantCulture.

Vea el siguiente enlace:

En C #, ¿cuál es la diferencia entre ToUpper () y ToUpperInvariant ()?