usar una longitud invertida ejemplos comparar como cadenas cadena alfabeticamente c# .net string-comparison ordinal

c# - una - Diferencia entre InvariantCulture y la comparación de cadenas ordinales



string.compare c# (9)

Cultura invariante

Utiliza un conjunto "estándar" de ordenación de caracteres (a, b, c, ... etc.). Esto contrasta con algunas configuraciones regionales específicas, que pueden ordenar los caracteres en diferentes órdenes (''a-with-acute'' puede ser antes o después de ''a'', dependiendo de la configuración regional, etc.).

Ordinal

Por otro lado, observa únicamente los valores de los bytes sin procesar que representan el carácter.

Hay una gran muestra en http://msdn.microsoft.com/en-us/library/e6883c06.aspx que muestra los resultados de los diversos valores de StringComparison. Hasta el final, se muestra (extraído):

StringComparison.InvariantCulture: LATIN SMALL LETTER I (U+0069) is less than LATIN SMALL LETTER DOTLESS I (U+0131) LATIN SMALL LETTER I (U+0069) is less than LATIN CAPITAL LETTER I (U+0049) LATIN SMALL LETTER DOTLESS I (U+0131) is greater than LATIN CAPITAL LETTER I (U+0049) StringComparison.Ordinal: LATIN SMALL LETTER I (U+0069) is less than LATIN SMALL LETTER DOTLESS I (U+0131) LATIN SMALL LETTER I (U+0069) is greater than LATIN CAPITAL LETTER I (U+0049) LATIN SMALL LETTER DOTLESS I (U+0131) is greater than LATIN CAPITAL LETTER I (U+0049)

Se puede ver que donde los rendimientos de InvariantCulture (U + 0069, U + 0049, U + 00131), los rendimientos ordinales (U + 0049, U + 0069, U + 00131).

Cuando se comparan dos cadenas en c # para igualdad, ¿cuál es la diferencia entre InvariantCulture y la comparación Ordinal?


Apuntando a las mejores prácticas para el uso de cadenas en .NET Framework :

  • Use StringComparison.Ordinal o StringComparison.OrdinalIgnoreCase para las comparaciones como su valor predeterminado seguro para la coincidencia de cadenas cultural-agnostic.
  • Utilice comparaciones con StringComparison.Ordinal o StringComparison.OrdinalIgnoreCase para obtener un mejor rendimiento.
  • Utilice los valores no lingüísticos StringComparison.Ordinal o StringComparison.OrdinalIgnoreCase lugar de las operaciones de cadena basadas en CultureInfo.InvariantCulture cuando la comparación es lingüísticamente irrelevante (simbólica, por ejemplo).

Y finalmente:

  • No utilice operaciones de cadena basadas en StringComparison.InvariantCulture en la mayoría de los casos . Una de las pocas excepciones es cuando persiste datos lingüísticamente significativos pero culturalmente agnósticos.

Aquí hay un ejemplo en el que la comparación de igualdad de cadenas usando InvariantCultureIgnoreCase y OrdinalIgnoreCase no dará los mismos resultados:

string str = "/xC4"; //A with umlaut, Ä string A = str.Normalize(NormalizationForm.FormC); //Length is 1, this will contain the single A with umlaut character (Ä) string B = str.Normalize(NormalizationForm.FormD); //Length is 2, this will contain an uppercase A followed by an umlaut combining character bool equals1 = A.Equals(B, StringComparison.OrdinalIgnoreCase); bool equals2 = A.Equals(B, StringComparison.InvariantCultureIgnoreCase);

Si ejecuta esto, equals1 será falso, y equals2 será verdadero.


Aunque la pregunta es acerca de la igualdad , para una referencia visual rápida, aquí el orden de algunas cadenas se ordenó utilizando un par de culturas que ilustran algunas de las idiosincrasias que existen.

Ordinal 0 9 A Ab a aB aa ab ss Ä Äb ß ä äb ぁ あ ァ ア 亜 A IgnoreCase 0 9 a A aa ab Ab aB ss ä Ä äb Äb ß ぁ あ ァ ア 亜 A -------------------------------------------------------------------- InvariantCulture 0 9 a A A ä Ä aa ab aB Ab äb Äb ss ß ァ ぁ ア あ 亜 IgnoreCase 0 9 A a A Ä ä aa Ab aB ab Äb äb ß ss ァ ぁ ア あ 亜 -------------------------------------------------------------------- da-DK 0 9 a A A ab aB Ab ss ß ä Ä äb Äb aa ァ ぁ ア あ 亜 IgnoreCase 0 9 A a A Ab aB ab ß ss Ä ä Äb äb aa ァ ぁ ア あ 亜 -------------------------------------------------------------------- de-DE 0 9 a A A ä Ä aa ab aB Ab äb Äb ß ss ァ ぁ ア あ 亜 IgnoreCase 0 9 A a A Ä ä aa Ab aB ab Äb äb ss ß ァ ぁ ア あ 亜 -------------------------------------------------------------------- en-US 0 9 a A A ä Ä aa ab aB Ab äb Äb ß ss ァ ぁ ア あ 亜 IgnoreCase 0 9 A a A Ä ä aa Ab aB ab Äb äb ss ß ァ ぁ ア あ 亜 -------------------------------------------------------------------- ja-JP 0 9 a A A ä Ä aa ab aB Ab äb Äb ß ss ァ ぁ ア あ 亜 IgnoreCase 0 9 A a A Ä ä aa Ab aB ab Äb äb ss ß ァ ぁ ア あ 亜

Observaciones:

  • de-DE , ja-JP y en-US clasifican de la misma manera
  • Invariant solo clasifica ss y ß diferente de las tres culturas anteriores
  • da-DK clasifica de manera muy diferente
  • La bandera IgnoreCase importante para todas las culturas muestreadas.

El código utilizado para generar la tabla anterior:

var l = new List<string> { "0", "9", "A", "Ab", "a", "aB", "aa", "ab", "ss", "ß", "Ä", "Äb", "ä", "äb", "あ", "ぁ", "ア", "ァ", "A", "亜" }; foreach (var comparer in new[] { StringComparer.Ordinal, StringComparer.OrdinalIgnoreCase, StringComparer.InvariantCulture, StringComparer.InvariantCultureIgnoreCase, StringComparer.Create(new CultureInfo("da-DK"), false), StringComparer.Create(new CultureInfo("da-DK"), true), StringComparer.Create(new CultureInfo("de-DE"), false), StringComparer.Create(new CultureInfo("de-DE"), true), StringComparer.Create(new CultureInfo("en-US"), false), StringComparer.Create(new CultureInfo("en-US"), true), StringComparer.Create(new CultureInfo("ja-JP"), false), StringComparer.Create(new CultureInfo("ja-JP"), true), }) { l.Sort(comparer); Console.WriteLine(string.Join(" ", l)); }


Invariante es un tipo de comparación lingüísticamente apropiado.
Ordinal es un tipo binario de comparación. (Más rápido)
Ver siao2.com/2004/12/29/344136.aspx


No es necesario utilizar ejemplos de caracteres de fantasía de Unicode para mostrar la diferencia. Este es un ejemplo simple que descubrí hoy que es sorprendente, y consiste en solo caracteres ASCII.

Según la tabla ASCII, 0 (0x48) es más pequeño que _ (0x95) cuando se compara de manera ordinaria. InvariantCulture diría lo contrario (código PowerShell a continuación):

PS> [System.StringComparer]::Ordinal.Compare("_", "0") 47 PS> [System.StringComparer]::InvariantCulture.Compare("_", "0") -1


Otra diferencia útil (en inglés donde los acentos son poco comunes) es que una comparación de InvariantCulture compara las cadenas completas por mayúsculas y minúsculas, y luego si es necesario (y solicitado) se distingue por caso después de comparar primero solo en las distintas letras. (Por supuesto, también puede hacer una comparación que no distinga entre mayúsculas y minúsculas, que no distinguirá entre mayúsculas y minúsculas). Corregido: las letras acentuadas se consideran otro sabor de las mismas letras y la cadena se compara primero ignorando acentos y luego contabilizándolos si las letras generales coinciden (tanto como con un caso diferente, excepto que no se ignoran en última instancia en una comparación que no distingue entre mayúsculas y minúsculas). Esto agrupa las versiones acentuadas de la misma palabra, por lo demás, cerca de la otra, en lugar de separarse completamente en la primera diferencia de acento. Este es el orden de clasificación que normalmente encontraría en un diccionario, con las palabras en mayúsculas que aparecen justo al lado de sus equivalentes en minúsculas, y las letras acentuadas están cerca de la letra correspondiente sin acentos.

Una comparación ordinal se compara estrictamente con los valores de caracteres numéricos, deteniéndose en la primera diferencia. Esto ordena las letras mayúsculas completamente separadas de las letras minúsculas (y las letras acentuadas presumiblemente separadas de esas), por lo que las palabras mayúsculas no se clasificarían en ninguna parte cerca de sus equivalentes en minúsculas.

InvariantCulture también considera que las mayúsculas son más grandes que las minúsculas, mientras que Ordinal considera que las mayúsculas son menos que en minúsculas (un remanente de ASCII de los viejos tiempos antes de que las computadoras tuvieran letras minúsculas, las mayúsculas se asignaron primero y por lo tanto tenían valores más bajos que las minúsculas añadido más tarde).

Por ejemplo, por ordinal: "0" < "9" < "A" < "Ab" < "Z" < "a" < "aB" < "ab" < "z" < "Á" < "Áb" < "á" < "áb"

Y por InvariantCulture: "0" < "9" < "a" < "A" < "á" < "Á" < "ab" < "aB" < "Ab" < "áb" < "Áb" < "z" < "Z"


Sí importa, por ejemplo, hay una cosa llamada expansión de caracteres.

var s1 = "Strasse"; var s2 = "Straße"; s1.Equals(s2, StringComparison.Ordinal); //false s1.Equals(s2, StringComparison.InvariantCulture); //true

Con InvariantCulture el carácter ß se expande a ss.


Siempre intente usar InvariantCulture en aquellos métodos de cadena que lo acepten como sobrecarga. Al usar InvariantCulture estás en un lado seguro. Es posible que muchos programadores .NET no utilicen esta funcionalidad, pero si su software será utilizado por diferentes culturas, InvariantCulture es una característica extremadamente útil.