una separar programacion por longitud ejemplos definicion comparar caracteres caracter cadenas cadena c# resharper configuration-files cultureinfo string-comparison

c# - separar - ¿Las comparaciones de cadenas realmente podrían diferir en función de la cultura cuando se garantiza que la cadena no cambiará?



string definicion (3)

Estoy leyendo credenciales / cadenas de conexión cifradas desde un archivo de configuración. Resharper me dice: "String.IndexOf (string) es específico de la cultura aquí" en esta línea:

if (line.Contains("host=")) { _host = line.Substring(line.IndexOf( "host=") + "host=".Length, line.Length - "host=".Length);

... y entonces quiere cambiarlo a:

if (line.Contains("host=")) { _host = line.Substring(line.IndexOf("host=", System.StringComparison.Ordinal) + "host=".Length, line.Length - "host=".Length);

El valor que estoy leyendo siempre será "host =" independientemente de dónde se implemente la aplicación. ¿Es realmente sensato agregar este bit "System.StringComparison.Ordinal"?

Más importante aún, ¿podría lastimar algo (usarlo)?


Absolutamente. Por MSDN ( http://msdn.microsoft.com/en-us/library/d93tkzah.aspx ),

Este método realiza una búsqueda de palabras (sensible a mayúsculas y minúsculas ) con la cultura actual.

Por lo tanto, puede obtener resultados diferentes si lo ejecuta en una cultura diferente (a través de la configuración regional y de idioma en el Panel de control).

En este caso particular, probablemente no tengas ningún problema, pero arroja una i en la cadena de búsqueda y ejecútala en Turquía, y probablemente arruine tu día.

Vea MSDN: http://msdn.microsoft.com/en-us/library/ms973919.aspx

Estas nuevas recomendaciones y API existen para aliviar las suposiciones erróneas sobre el comportamiento de las API de cadenas predeterminadas. El ejemplo canónico de errores emergentes donde los datos de cadenas no lingüísticas se interpretan lingüísticamente es el problema del "Turco-I".

Para casi todos los alfabetos latinos, incluido el inglés de EE. UU., El carácter i (/ u0069) es la versión en minúscula del carácter I (/ u0049). Esta regla de la carcasa se convierte rápidamente en la predeterminada para alguien que programa en dicha cultura. Sin embargo, en turco ("tr-TR"), existe un carácter mayúscula "i with a dot" (/ u0130), que es la versión capital de i. Del mismo modo, en turco, hay una minúscula "i sin punto", o (/ u0131), que escribe en mayúscula a I. Este comportamiento también ocurre en la cultura azerí ("az").

Por lo tanto, las suposiciones que normalmente se hacen sobre capitalizar i o minúsculas I no son válidas entre todas las culturas. Si se usan las sobrecargas predeterminadas para las rutinas de comparación de cadenas, estarán sujetas a la variación entre culturas. Para datos no lingüísticos, como en el siguiente ejemplo, esto puede producir resultados no deseados:

Thread.CurrentThread.CurrentCulture = new CultureInfo("en-US") Console.WriteLine("Culture = {0}", Thread.CurrentThread.CurrentCulture.DisplayName); Console.WriteLine("(file == FILE) = {0}", (String.Compare("file", "FILE", true) == 0)); Thread.CurrentThread.CurrentCulture = new CultureInfo("tr-TR"); Console.WriteLine("Culture = {0}", Thread.CurrentThread.CurrentCulture.DisplayName); Console.WriteLine("(file == FILE) = {0}", (String.Compare("file", "FILE", true) == 0));

Debido a la diferencia de la comparación de I, los resultados de las comparaciones cambian cuando se cambia el cultivo de hilo. Este es el resultado:

Culture = English (United States) (file == FILE) = True Culture = Turkish (Turkey) (file == FILE) = False

Aquí hay un ejemplo sin caso:

var s1 = "é"; //é as one character (ALT+0233) var s2 = "é"; //''e'', plus combining acute accent U+301 (two characters) Console.WriteLine(s1.IndexOf(s2, StringComparison.Ordinal)); //-1 Console.WriteLine(s1.IndexOf(s2, StringComparison.InvariantCulture)); //0 Console.WriteLine(s1.IndexOf(s2, StringComparison.CurrentCulture)); //0


Para responder a su pregunta específica: No, pero una herramienta de análisis estático no podrá darse cuenta de que su valor de entrada nunca tendrá información específica de la configuración regional.


CA1309: UseOrdinalStringComparison

No está de más no usarlo, pero " estableciendo explícitamente el parámetro en StringComparison.Ordinal o StringComparison.OrdinalIgnoreCase, su código a menudo gana velocidad, aumenta la corrección y se vuelve más confiable ".

¿Qué es exactamente Ordinal y por qué es importante para su caso?

Una operación que usa reglas de ordenamiento ordinal realiza una comparación basada en el valor numérico (punto de código Unicode) de cada Char en la cadena. Una comparación ordinal es rápida pero insensible a la cultura. Cuando utiliza reglas de ordenación ordinales para ordenar cadenas que comienzan con caracteres Unicode (U +), la cadena U + xxxx aparece antes de la cadena U + yyyy si el valor de xxxx es numéricamente menor que aaaa.

Y, como dijiste ... el valor de la cadena que estás leyendo no es sensible a la cultura, por lo que tiene sentido usar una comparación Ordinal en comparación con una comparación de Word. Solo recuerde, Ordinal significa "esto no es culturalmente sensible".