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?
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 ejemplo 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 más información sobre turco, ver este Turkey Test blog post.
No me sorprendería saber que existen otros problemas de mayúsculas en torno a los caracteres elásticos, etc. Este es solo un ejemplo que sé de sobra ... en parte porque me mordió hace años en Java, donde estaba haciendo una cadena superior y comparándola con "CORREO". Eso no funcionó tan bien en Turquía ...
jaja Leí eso pensando ... "'Turquía' no tiene una letra 'yo' en él" –
Violín que ilustra lo mismo: https://dotnetfiddle.net/x3uqwa – KorsG
http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant.aspx
documentación de Microsoft explica las diferencias y da ejemplos de resultados diferentes.
de inicio con MSDN
http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant.aspx
El método ToUpperInvariant es equivalente a ToUpper (CultureInfo.InvariantCulture)
hecho de que un capital de i es 'I' en inglés, no siempre lo hace así.
ToUpperInvariant utiliza las reglas de la invariant culture
no hay ninguna diferencia en Inglés. solo en la cultura turca se puede encontrar una diferencia.
Y está seguro de que el turco es el única cultura en el mundo que tiene diferentes reglas para mayúsculas que inglés? Me parece difícil de creer. –
El turco es el ejemplo más utilizado, pero no el único. Y es el lenguaje, no la cultura, lo que tiene cuatro I diferentes. Aún así, +1 para turco. – Armstrongest
seguro que debe haber algunos otros. la mayoría de las personas nunca se encontrarán con esos idiomas en la programación de todos modos – Stefanvds
La respuesta de Jon es perfecta. Solo quería agregar que ToUpperInvariant
es lo mismo que llamar al ToUpper(CultureInfo.InvariantCulture)
.
Eso hace que el ejemplo de Jon 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 },
}
});
}
}
que también utilizaron Times New Roman porque es un tipo de letra más fresco.
Asimismo, establecer la propiedad Font
la Form
's en 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.
"La respuesta de Jon es perfecta". Habla sobre una declaración redundante. ;) – krillgar
El método ToUpper no tiene ninguna sobrecarga de parámetros para mí? Qué versión más antigua tiene? No lo entiendo – batmaci
No lo sé, está documentado aquí: https://msdn.microsoft.com/en-us/library/system.string.toupper.aspx – Tergiver
String.ToUpper
y String.ToLower
pueden dar resultados diferentes según las diferentes culturas. El ejemplo más conocido es the Turkish example, por lo que la conversión de "i" en mayúscula en minúscula a mayúscula no da como resultado una "I" en mayúscula en mayúscula, sino en "I" en turco.
En cuanto a mí era confuso, incluso con la imagen de arriba (source), que escribió un programa (ver código fuente abajo) para ver la salida exacta 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 se puede ver:
Culture.CultureInvariant
deja a los caracteres turcos como esToUpper
ToLower
y son reversibles, es decir un carácter en minúscula después uppercasing él, lo lleva a la forma original, siempre que para ambas operaciones se utilizó la misma cultura.Según MSDN, por Char.ToUpper y Char.ToLower turco y azerbaiyano son los únicos cultivos afectados, ya que son los únicos que tienen diferencias de la carcasa de un solo carácter. Para cuerdas, puede haber más culturas afectadas.
El código fuente de una aplicación de consola que se utiliza 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})";
}
}
}
[Organización] En caso de que esta pregunta tiene etiqueta "internacionalización"? – jasso