Que generalmente es 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?

Author: Arjan Einbu, 2008-09-16

6 answers

De las "Nuevas Recomendaciones para Usar Cadenas en Microsoft. NET 2.0"

Resumen: Los propietarios de código que hayan utilizado anteriormente la InvariantCulture para comparar cadenas, encajonar y ordenar deben considerar seriamente el uso de un nuevo conjunto de sobrecargas de cadenas 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 la comparación de cadenas.Ordinal o StringComparison.OrdenalIgnoreCase miembros de la nueva enumeración StringComparison. Estos imponen una comparación byte-by-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)

 134
Author: Robert Taylor,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-16 14:16:42

Todo depende

Comparar cadenas unicode es difícil:

La implementación de la cadena Unicode búsquedas y comparaciones en texto el software de procesamiento debe tomar en cuenta la presencia de equivalente puntos clave. En ausencia de esto característica, los usuarios que buscan un particular secuencia de punto de código sería ser incapaz de encontrar otro visualmente glifos indistinguibles que tienen un diferente, pero canónicamente equivalente, punto de código representatividad.

Véase: http://en.wikipedia.org/wiki/Unicode_equivalence


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

El ejemplo clásico es el turco i , que cuando mayúsculas se convierte en I (observe el punto)

De forma predeterminada,. Net framework generalmente usa CurrentCulture para funciones relacionadas con cadenas, con una excepción muy importante de .Equals que usa un ordinal (byte por byte) compare.

Esto conduce, 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", insensible a 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é equipo 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 usando reglas de equivalencia unicode.
  2. Establezca la cultura a la Cultura Invariante y realice una comparación insensible a mayúsculas y minúsculas usando reglas de equivalencia unicode.
  3. Use OrdinalIgnoreCase que pondrá mayúsculas a la cadena usando la 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 caro que OrdinalIgnoreCase. El hecho de que OrdinalIgnoreCase no realice ninguna normalización unicode especial, significa que algunas cadenas que se renderizan de la misma manera en una pantalla de 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.

El que elija depende en gran medida de la aplicación que esté compilando.

  • Si estaba escribiendo una aplicación de línea de negocio que solo era utilizada por usuarios turcos, estaría seguro de utilizar el método 1.
  • Si solo necesitara una simple comparación "falsa" insensible a mayúsculas y minúsculas, 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 directrices 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 muy especial tipo de bestia, que es recoger y elegir un poco de un ordinal comparar con algunos mezclados en aspectos lexicográficos. Esto puede ser confuso.

 51
Author: Sam Saffron,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2014-10-08 17:07:09

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

 8
Author: chessguy,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-16 14:13:41

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

 3
Author: Bullines,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-16 14:17:22

Depende de lo que quieras, aunque yo evitaría invariantculture a menos que estés muy seguro de que nunca querrás localizar el código para otros lenguajes. Usa CurrentCulture en su lugar.

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

 1
Author: Joel Coehoorn,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2008-09-16 14:13:00

La respuesta muy simple es, a menos que esté usando turco, no necesita usar InvariantCulture.

Ver el siguiente enlace:

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

 0
Author: TheMoot,
Warning: date(): Invalid date.timezone value 'Europe/Kyiv', we selected the timezone 'UTC' for now. in /var/www/agent_stack/data/www/ajaxhispano.com/template/agent.layouts/content.php on line 61
2017-05-23 12:34:20