Em C #, qual é a diferença entre ToUpper()
e ToUpperInvariant()
?
Você pode dar um exemplo em que os resultados podem ser diferentes?
Em C #, qual é a diferença entre ToUpper()
e ToUpperInvariant()
?
Você pode dar um exemplo em que os resultados podem ser diferentes?
Respostas:
ToUpper
usa a cultura atual. ToUpperInvariant
usa a cultura invariável.
O exemplo canônico é a Turquia, onde a letra maiúscula de "i" não é "I".
Código de exemplo mostrando a diferença:
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 saber mais sobre turco, consulte esta postagem no blog Turkey Test .
Eu não ficaria surpreso ao saber que existem vários outros problemas de maiúsculas em torno de personagens elidificados etc. -casando uma string e comparando-a com "MAIL". Isso não funcionou tão bem na Turquia ...
ımage
como um nome de campo para o Image
Unity 3D enviar um spam para um erro interno no console Unable to find key name that matches 'rıght'
em um Windows "inglês" com as configurações regionais da Turquia para data e hora. Parece que, às vezes, até a Microsoft falha no teste da Turquia, o idioma de um PC nem sequer é turco, apenas risos.
A resposta de Jon é perfeita. Eu só queria acrescentar que ToUpperInvariant
é o mesmo que ligar ToUpper(CultureInfo.InvariantCulture)
.
Isso torna o exemplo de Jon um pouco mais simples:
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 },
}
});
}
}
Eu também usei o New Times Roman porque é uma fonte mais legal.
Eu também definir o Form
's Font
propriedade em vez dos dois Label
controles porque a Font
propriedade é herdada.
E reduzi algumas outras linhas apenas porque gosto de código compacto (por exemplo, não de produção).
Eu realmente não tinha nada melhor para fazer no momento.
Comece com o MSDN
http://msdn.microsoft.com/en-us/library/system.string.toupperinvariant.aspx
O método ToUpperInvariant é equivalente a ToUpper (CultureInfo.InvariantCulture)
Só porque um capital i é 'I' em inglês, nem sempre é assim.
String.ToUpper
e String.ToLower
pode dar resultados diferentes, dadas culturas diferentes. O exemplo mais conhecido é o exemplo turco , para o qual converter latim minúsculo "i" em maiúsculo não resulta em latim maiúsculo "I", mas no turco "I".
Quanto a mim, foi confuso, mesmo com a imagem acima ( fonte ), escrevi um programa (veja o código-fonte abaixo) para ver a saída exata do exemplo 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 você pode ver:
Culture.CultureInvariant
deixa os caracteres turcos como estãoToUpper
e ToLower
são reversíveis, que colocam um caractere em minúsculas e depois em maiúsculas, o traz para a forma original, desde que para ambas as operações a mesma cultura tenha sido usada.De acordo com o MSDN , para Char.ToUpper e Char.ToLower Turco e Azeri são as únicas culturas afetadas porque são as únicas com diferenças de revestimento de caractere único. Para strings, pode haver mais culturas afetadas.
Código-fonte de um aplicativo de console usado para gerar a saída:
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 as regras da cultura invariável
não há diferença em inglês. somente na cultura turca é possível encontrar uma diferença.