En C #, ¿cuál es la diferencia entre ToUpper()
y ToUpperInvariant()
?
¿Puedes dar un ejemplo donde los resultados podrían ser diferentes?
En C #, ¿cuál es la diferencia entre ToUpper()
y ToUpperInvariant()
?
¿Puedes dar un ejemplo donde los resultados podrían ser diferentes?
Respuestas:
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, vea esta publicación del blog Prueba de Turquía .
No me sorprendería saber que hay varios otros problemas de capitalización en torno a los caracteres elididos, etc. Este es solo un ejemplo que conozco fuera de mi cabeza ... en parte porque me mordió hace años en Java, donde era superior -envolviendo una cadena y comparándola con "CORREO". Eso no funcionó tan bien en Turquía ...
ımage
como nombre de campo Image
y Unity 3D enviando un error interno a la consola Unable to find key name that matches 'rıght'
en un Windows "inglés" con configuraciones regionales de Turquía para fecha y hora. Parece que a veces incluso Microsoft falla la prueba de Turquía, el idioma de una PC ni siquiera es turco, solo jajaja.
La respuesta de Jon es perfecta. Solo quería agregar que ToUpperInvariant
es lo mismo que llamar 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 usé New Times Roman porque es una fuente más genial.
También configuré la propiedad de Form
's en Font
lugar de los dos Label
controles porque la Font
propiedad se hereda.
Y reduje algunas otras líneas solo porque me gusta el código compacto (ejemplo, no 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)
El hecho de que una i mayúscula sea "yo" en inglés, no siempre lo hace así.
String.ToUpper
y String.ToLower
puede dar diferentes resultados dados diferentes culturas. El ejemplo más conocido es el ejemplo turco , para el cual la conversión de minúsculas latinas "i" a mayúsculas, no da como resultado una "I" latina mayúscula, sino la "I" turca.
En cuanto a mí, fue confuso incluso con la imagen de arriba ( fuente ), escribí un programa (vea el código fuente a continuación) para ver la salida exacta del 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:
Culture.CultureInvariant
deja los caracteres turcos como estánToUpper
y ToLower
son reversibles, es decir, un carácter en minúsculas después de ponerlo en mayúscula, lo lleva a la forma original, siempre y cuando para ambas operaciones se haya utilizado la misma cultura.Según MSDN , para Char.ToUpper y Char.ToLower, el turco y el azerí son las únicas culturas afectadas porque son las únicas con diferencias de carcasa de un solo carácter. Para las cuerdas, puede haber más culturas afectadas.
Código fuente de una aplicación de consola utilizada para generar la salida:
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})";
}
}
}
ToUpperInvariant usa las reglas de la cultura invariante
No hay diferencia en inglés. solo en la cultura turca se puede encontrar una diferencia.