lower - En C#, ¿cuál es la diferencia entre ToUpper() y ToUpperInvariant()?
uppercase c# example (7)
En C #, ¿cuál es la diferencia entre ToUpper()
y ToUpperInvariant()
?
¿Puedes dar un ejemplo donde los resultados pueden ser diferentes?
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í.
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.
ToUpperInvariant usa las reglas de la http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant.aspx
no hay diferencia en inglés. solo en la cultura turca se puede encontrar una diferencia.
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.
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.
En cuanto a mí, fue confuso incluso con la imagen de arriba ( source ), escribí un programa (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:
- Las mayúsculas minúsculas y las mayúsculas minúsculas dan resultados diferentes para la cultura invariante y la cultura turca.
- 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.
-
Culture.CultureInvariant
deja los caracteres turcos como está -
ToUpper
yToLower
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 source , 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})";
}
}
}
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 ...