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

Resuelto Dave Haynes asked hace 16 años • 5 respuestas

Tengo un código como este:

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

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

Dave Haynes avatar Sep 16 '08 21:09 Dave Haynes
Aceptado

Los documentos .Net más nuevos ahora tienen una tabla para ayudarlo a decidir cuál es mejor usar en su situación.

De " Nuevas recomendaciones para el uso de cadenas en Microsoft .NET 2.0 " de MSDN

Resumen: Los propietarios de código que anteriormente utilizaban la InvariantCulturefunción de comparación, mayúsculas y ordenación de cadenas deberían considerar seriamente el uso de un nuevo conjunto de Stringsobrecargas en Microsoft .NET 2.0. Específicamente, los datos que están diseñados para ser independientes de la cultura y lingüísticamente irrelevantes deben comenzar a especificar sobrecargas utilizando los miembros StringComparison.Ordinalo StringComparison.OrdinalIgnoreCasede la nueva StringComparisonenumeración. Estos imponen una comparación byte por byte similar a strcmpla que no solo evita errores de interpretación lingüística de cadenas esencialmente simbólicas, sino que también proporciona un mejor rendimiento.

Robert Taylor avatar Sep 16 '2008 14:09 Robert Taylor

Todo depende

Comparar cadenas Unicode es difícil:

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

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


Si está intentando comparar 2 cadenas Unicode sin distinguir entre mayúsculas y minúsculas y desea que funcione EN TODAS PARTES , tiene un problema imposible.

El ejemplo clásico es la i turca , que cuando está en mayúscula se convierte en İ (observe el punto)

De forma predeterminada, el marco .Net generalmente usa CurrentCulture para funciones relacionadas con cadenas, con una excepción muy importante que .Equalsusa una comparación ordinal (byte por byte).

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


Sin embargo, a veces queremos una comparación de "propósito general", que no distinga entre mayúsculas y minúsculas.

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

Para conseguirlo tenemos 3 opciones:

  1. Establezca la cultura explícitamente y realice una comparación que no distinga entre mayúsculas y minúsculas utilizando reglas de equivalencia Unicode.
  2. Establezca la cultura en Cultura invariante y realice una comparación que no distinga entre mayúsculas y minúsculas utilizando reglas de equivalencia Unicode.
  3. Utilice OrdinalIgnoreCase , que pondrá en mayúsculas la cadena utilizando InvariantCulture y luego realizará 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 OrdinalIgnoreCaseno realice ninguna normalización 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 representan å. Sin embargo, en una comparación ordinal se considerará diferente.

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

  • Si estuviera escribiendo una aplicación de línea de negocio que solo fuera utilizada por usuarios turcos, me aseguraría de usar el método 1.
  • Si solo necesitara una simple comparación "falsa" que no distinga entre mayúsculas y minúsculas, por ejemplo, un nombre de columna en una base de datos, que generalmente está en inglés, probablemente usaría el método 3.

Microsoft tiene su conjunto de recomendaciones con pautas explícitas. Sin embargo, es realmente importante comprender 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 selecciona y elige un poco ordinal en comparación con algunos aspectos lexicográficos mixtos. Esto puede resultar confuso.

Sam Saffron avatar Jun 20 '2011 02:06 Sam Saffron