it-swarm-es.tech

¿Cuál es generalmente el mejor uso - 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?

138
Dave Haynes

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

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

Resumen: los propietarios de código que usaron anteriormente la InvariantCulture para la comparación de cadenas, el encofrado y la clasificación deberían considerar seriamente el uso de un nuevo conjunto de String sobrecargas 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.Ordinal o StringComparison.OrdinalIgnoreCase de la nueva enumeración StringComparison. Estos hacen cumplir una comparación byte a byte similar a strcmp que no solo evita los errores de la interpretación lingüística de cadenas esencialmente simbólicas, sino que también proporciona un mejor rendimiento.

151
Robert Taylor

Todo depende

Comparar las cadenas de Unicode es difícil:

La implementación de búsquedas y comparaciones de cadenas de Unicode en el software de procesamiento de texto debe tener en cuenta la presencia de puntos de código equivalentes. En ausencia de esta función, los usuarios que buscan una secuencia de punto de código particular no podrán encontrar otros glifos que no se distinguen visualmente y 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 Unicode de una manera que no distingue entre mayúsculas y minúsculas y desea que funcioneEN TODAS PARTES, tiene un problema imposible.

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

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

Esto lleva, 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", que no distinga mayúsculas y minúsculas.

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

Para lograrlo tenemos 3 opciones:

  1. Establezca la cultura explícitamente y realice una comparación que no distinga mayúsculas y minúsculas utilizando las reglas de equivalencia de Unicode.
  2. Establezca la cultura en Cultura invariante y realice una comparación que no distinga mayúsculas de minúsculas utilizando las reglas de equivalencia de Unicode.
  3. Use OrdinalIgnoreCase que hará mayúsculas en la cadena usando InvariantCulture y luego realizará una comparación byte a byte.

Las reglas de equivalencia de 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 especial de Unicode, significa que algunas cadenas que se renderizan de la misma manera en la pantalla de una computadora, no lo hará se considerarán idénticas. Por ejemplo: "\u0061\u030a" y "\u00e5" ambos render å. Sin embargo en una comparación ordinal se considerarán diferentes.

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

  • Si escribiera una aplicación de línea de negocio que solo utilizaban los usuarios turcos, me aseguraría de utilizar el método 1.
  • Si solo necesitara una comparación simple "falsa" que no distinga mayúsculas y minúsculas, por ejemplo, un nombre de columna en una base de datos, que generalmente es 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 de Unicode antes de abordar estos problemas.

Además, tenga en cuenta que OrdinalIgnoreCase es una clase muy especial de bestia, que consiste en escoger y elegir un poco de ordinal en comparación con algunos aspectos lexicográficos mezclados. Esto puede ser confuso.

56
Sam Saffron

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

8
chessguy

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

3
Bullines

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

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

1
Joel Coehoorn

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

Vea el siguiente enlace:

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

0
TheMoot