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

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

¿Puedes dar un ejemplo donde los resultados pueden ser diferentes?

ToUpper usa la cultura actual. ToUpperInvariant usa la cultura invariante.

El ejemplo canónico es Turquía, donde la mayúscula de “i” no es “I”.

Código de muestra que muestra la diferencia:

 using System; using System.Drawing; using System.Globalization; using System.Threading; using System.Windows.Forms; public class Test { [STAThread] static void Main() { string invariant = "iii".ToUpperInvariant(); CultureInfo turkey = new CultureInfo("tr-TR"); Thread.CurrentThread.CurrentCulture = turkey; string cultured = "iii".ToUpper(); Font bigFont = new Font("Arial", 40); Form f = new Form { Controls = { new Label { Text = invariant, Location = new Point(20, 20), Font = bigFont, AutoSize = true}, new Label { Text = cultured, Location = new Point(20, 100), Font = bigFont, AutoSize = true } } }; Application.Run(f); } } 

Para obtener más información sobre el turco, consulte esta publicación del blog Turkey Test .

No me sorprendería escuchar que hay varios otros problemas de capitalización alrededor de los caracteres eliminados, etc. Este es solo un ejemplo que conozco en la cabeza … en parte porque me mordió hace años en Java, donde era superior -cadenando una cuerda y comparándola con “CORREO”. Eso no funcionó tan bien en Turquía …

La respuesta de Jon es perfecta. Solo quería agregar que ToUpperInvariant es lo mismo que llamar a ToUpper(CultureInfo.InvariantCulture) .

Eso hace que el ejemplo de Jon sea un poco más simple:

 using System; using System.Drawing; using System.Globalization; using System.Threading; using System.Windows.Forms; public class Test { [STAThread] static void Main() { string invariant = "iii".ToUpper(CultureInfo.InvariantCulture); string cultured = "iii".ToUpper(new CultureInfo("tr-TR")); Application.Run(new Form { Font = new Font("Times New Roman", 40), Controls = { new Label { Text = invariant, Location = new Point(20, 20), AutoSize = true }, new Label { Text = cultured, Location = new Point(20, 100), AutoSize = true }, } }); } } 

También utilicé New Times Roman porque es una fuente más fresca.

También configuré la propiedad Font del Form lugar de los dos controles Label porque la propiedad Font se hereda.

Y reduje algunas otras líneas solo porque me gusta el código compacto (por ejemplo, no la producción).

Realmente no tenía nada mejor que hacer en este momento.

Comience con MSDN

http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant.aspx

El método ToUpperInvariant es equivalente a ToUpper (CultureInfo.InvariantCulture)

Solo porque un capital i sea “I” en inglés, no siempre lo hace así.

String.ToUpper y String.ToLower pueden dar resultados diferentes en diferentes culturas. El ejemplo más conocido es el ejemplo turco , para el cual la conversión de la “i” latina en minúscula a mayúscula, no da como resultado una “I” en mayúscula en mayúscula, sino en la “I” turca.

Capitalización de I dependiendo de la cultura, fila superior - minúsculas, fila inferior - letras mayúsculas

En cuanto a mí, fue confuso incluso con la imagen de arriba ( fuente ), escribí un progtwig (vea el código fuente a continuación) para ver el resultado exacto para el ejemplo turco:

 # Lowercase letters Character | UpperInvariant | UpperTurkish | LowerInvariant | LowerTurkish English i - i (\u0069) | I (\u0049) | I (\u0130) | i (\u0069) | i (\u0069) Turkish i - ı (\u0131) | ı (\u0131) | I (\u0049) | ı (\u0131) | ı (\u0131) # Uppercase letters Character | UpperInvariant | UpperTurkish | LowerInvariant | LowerTurkish English i - I (\u0049) | I (\u0049) | I (\u0049) | i (\u0069) | ı (\u0131) Turkish i - I (\u0130) | I (\u0130) | I (\u0130) | I (\u0130) | i (\u0069) 

Como puedes ver:

  1. Las mayúsculas minúsculas y las mayúsculas minúsculas dan resultados diferentes para la cultura invariante y la cultura turca.
  2. Las letras mayúsculas en mayúscula y minúsculas en minúscula no tienen ningún efecto, no importa cuál sea la cultura.
  3. Culture.CultureInvariant deja los caracteres turcos como está
  4. ToUpper y ToLower son reversibles, es decir, la minúscula de un carácter después de mayúsculas, lo lleva a la forma original, siempre y cuando para ambas operaciones se use la misma cultura.

Según MSDN , para Char.ToUpper y Char.ToLower, los turcos y los azeríes son los únicos cultivos afectados porque son los únicos con diferencias de carcasa de un solo carácter. Para cuerdas, puede haber más culturas afectadas.


Código fuente de una aplicación de consola utilizada para generar el resultado:

 using System; using System.Globalization; using System.Linq; using System.Text; namespace TurkishI { class Program { static void Main(string[] args) { var englishI = new UnicodeCharacter('\u0069', "English i"); var turkishI = new UnicodeCharacter('\u0131', "Turkish i"); Console.WriteLine("# Lowercase letters"); Console.WriteLine("Character | UpperInvariant | UpperTurkish | LowerInvariant | LowerTurkish"); WriteUpperToConsole(englishI); WriteLowerToConsole(turkishI); Console.WriteLine("\n# Uppercase letters"); var uppercaseEnglishI = new UnicodeCharacter('\u0049', "English i"); var uppercaseTurkishI = new UnicodeCharacter('\u0130', "Turkish i"); Console.WriteLine("Character | UpperInvariant | UpperTurkish | LowerInvariant | LowerTurkish"); WriteLowerToConsole(uppercaseEnglishI); WriteLowerToConsole(uppercaseTurkishI); Console.ReadKey(); } static void WriteUpperToConsole(UnicodeCharacter character) { Console.WriteLine("{0,-9} - {1,10} | {2,-14} | {3,-12} | {4,-14} | {5,-12}", character.Description, character, character.UpperInvariant, character.UpperTurkish, character.LowerInvariant, character.LowerTurkish ); } static void WriteLowerToConsole(UnicodeCharacter character) { Console.WriteLine("{0,-9} - {1,10} | {2,-14} | {3,-12} | {4,-14} | {5,-12}", character.Description, character, character.UpperInvariant, character.UpperTurkish, character.LowerInvariant, character.LowerTurkish ); } } class UnicodeCharacter { public static readonly CultureInfo TurkishCulture = new CultureInfo("tr-TR"); public char Character { get; } public string Description { get; } public UnicodeCharacter(char character) : this(character, string.Empty) { } public UnicodeCharacter(char character, string description) { if (description == null) { throw new ArgumentNullException(nameof(description)); } Character = character; Description = description; } public string EscapeSequence => ToUnicodeEscapeSequence(Character); public UnicodeCharacter LowerInvariant => new UnicodeCharacter(Char.ToLowerInvariant(Character)); public UnicodeCharacter UpperInvariant => new UnicodeCharacter(Char.ToUpperInvariant(Character)); public UnicodeCharacter LowerTurkish => new UnicodeCharacter(Char.ToLower(Character, TurkishCulture)); public UnicodeCharacter UpperTurkish => new UnicodeCharacter(Char.ToUpper(Character, TurkishCulture)); private static string ToUnicodeEscapeSequence(char character) { var bytes = Encoding.Unicode.GetBytes(new[] {character}); var prefix = bytes.Length == 4 ? @"\U" : @"\u"; var hex = BitConverter.ToString(bytes.Reverse().ToArray()).Replace("-", string.Empty); return $"{prefix}{hex}"; } public override string ToString() { return $"{Character} ({EscapeSequence})"; } } } 

http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant.aspx

La documentación de Microsoft explica las diferencias y ofrece ejemplos de resultados diferentes.

ToUpperInvariant usa las reglas de la cultura invariante

no hay diferencia en inglés. solo en la cultura turca se puede encontrar una diferencia.