![]() |
Hoje veremos como a localização pode afetar a manipulação de strings na linguagem C#. |
Na plataforma .NET, todas as operações com strings baseadas na cultura usam a cultura atual que é definida para a thread atual ( propriedade CurrentCulture de Thread.CurrentThread), a menos que uma cultura diferente seja especificada para um chamada específica.
Por padrão, o valor da propriedade
CurrentCulture corresponde
à região dos usuários e configurações de idioma no
sistema operacional, que é o que o usuário normalmente
espera.
O fato do comportamento depender das configurações do
usuário tornam esses padrões inadequados para
processamento interno de strings e comunicação entre
diferentes componentes e sistemas.
Em tais cenários, é melhor que os resultados sejam sempre iguais. Isso pode ser alcançado alterando a propriedade CurrentCulture na thread ou especificando a cultura desejada para cada operação.
As operações mais óbvias afetadas pelas configurações de cultura são a formatação de datas e os valores numéricos. Assim, quando o método ToString for chamado em um valor sem uma cultura especificada, o valor de CurrentCulture será usado.
Vejamos a seguir alguns exemplos que foram feitos usando um projeto Console do tipo .NET Core no VS 2019 Community onde definimos os namespaces:
Vamos iniciar com a formatação de datas:
static void Main(string[] args) { Console.WriteLine($"O valor de CurrentCulture é {CultureInfo.CurrentCulture.Name}."); var data = new DateTime(2020, 9, 1);
var ptbrData = data.ToString("d");
Console.WriteLine($"{ptbrData}");
var eslovenaCultura = CultureInfo.GetCultureInfo("sl-SI");
Console.WriteLine($"Cultura Eslovênia = {eslovenaCultura}");
var slsiData = data.ToString("d", eslovenaCultura);
Console.WriteLine($"{slsiData}");
Console.ReadLine();
}
|
Resultado:
Neste exemplo a cultura padrão é pt-Br e a seguir definimos uma nova cultura eslovena (sl-SI) para obter a data em um formato diferente.
O mesmo ocorre com valores numéricos embora exista uma menor variedade em como os valores são formatados.
private static void CultureNumeros()
{
Console.WriteLine($"O valor de CurrentCulture é {CultureInfo.CurrentCulture.Name}.");
var pi = 3.14;
var ptbrPi = pi.ToString(); // = "3,14
Console.WriteLine($"{ptbrPi}");
var enusCulture = CultureInfo.GetCultureInfo("en-US");
Console.WriteLine($"Cultura Americana = {enusCulture}");
var enusPi = pi.ToString(enusCulture); // = "3.14
Console.WriteLine($"{enusPi}");
}
|
Resultado:
Podemos ainda especificar uma cultura fixa quando o método string.Format for usado para formatação composta. A mesma cultura será usada formatar todos os valores no formato string definidos:
static void Main(string[] args)
{
var eslovenaCulture = CultureInfo.GetCultureInfo("sl-SI");
var temperatura = 21.5;
var timestamp = new DateTime(2018, 9, 1, 16, 15, 30);
var formatString = "Temperatura: {0} °C em {1} ";
var formatopt_br = string.Format(formatString, temperatura, timestamp);
var formatosl_si = string.Format(eslovenaCulture, formatString ,temperatura, timestamp);
Console.WriteLine($"cultura {CultureInfo.CurrentCulture.Name}");
Console.WriteLine(formatopt_br);
Console.WriteLine($"cultura {eslovenaCulture}");
Console.WriteLine(formatosl_si);
Console.ReadLine();
}
|
A comparação de strings também é afetada pela localização. No exemplo abaixo vamos comparar a string eszett com um ss duplo na cultura atual e a seguir no Alemão. usando a comparação ordinal e cultural:
static void Main(string[] args)
{
Console.WriteLine($"Cultura atual = {CultureInfo.CurrentCulture.Name}.");
var doubleS = "ss";
var eszett = "ß"; //O eszett representa o fonema s no Alemão
var equalOrdinal = string.Equals(doubleS, eszett); // = false
Console.WriteLine($"{equalOrdinal}");
// Mudando a cultura atual para Alemão
CultureInfo.CurrentCulture = new CultureInfo("de-DE", false);
Console.WriteLine($"Cultura atual = {CultureInfo.CurrentCulture.Name}.");
var equalCulture = string.Equals(doubleS, eszett, StringComparison.CurrentCulture); // = true
Console.WriteLine($"{equalCulture}");
Console.ReadLine();
}
|
Os resultados da comparação de strings não mudam apenas com base na cultura. Existem duas configurações importantes adicionais:
A comparação padrão de strings no
.NET Framework é ordinal e diferencia maiúsculas de
minúsculas. É por isso que as dois maneiras diferentes,
mas equivalentes, de escrever o mesmo caractere em
alemão, são tratadas como
strings diferentes.
Quando as strings são comparadas de acordo com a cultura, a regra linguística é considerada e as strings são tratadas como iguais.
A comparação ordinal de cadeias
sem distinção entre maiúsculas e minúsculas é um caso
especial que merece
explicação.
Quando cadeias são comparadas de
acordo com esta regra, elas são convertidas internamente
para maiúsculas, usando a cultura invariável (uma
cultura especial baseada no idioma inglês sem
especificações regionais). Eles são comparados com
base na representação de byte, como no caso da
comparação ordinal padrão que diferencia maiúsculas de
minúsculas.
As configurações de comparação de strings também são
importantes ao classificar strings.
As coleções na biblioteca de classes base do .NET Framework tem uma opção para especificar as regras de classificação a serem usadas. Com base nessa configuração, as strings serão classificadas de maneira diferente na coleção conforme mostra o exemplo a seguir:
static void Main(string[] args)
{
var czCulture = CultureInfo.GetCultureInfo("cs-CZ");
var palavras = new[] { "channel", "double" };
var ordinalSortedSet = new SortedSet<string>(palavras);
Console.WriteLine(">>ordinal");
foreach (var palavra in ordinalSortedSet)
{
Console.WriteLine(palavra);
}
var cultureSortedSet = new SortedSet<string>(palavras,StringComparer.Create(czCulture, ignoreCase: true));
Console.WriteLine($"Cultura = {czCulture}");
Console.WriteLine(">>ignoreCase");
foreach (var palavra in cultureSortedSet)
{
Console.WriteLine(palavra);
}
Console.ReadLine();
}
|
Resultado:
Como usei o código de idioma tcheco para a segunda coleção, a ordem das duas strings foi invertida.
Isso acontece porque o idioma tcheco trata a sequência "ch" como um letra diferente de C. Ela está posicionada próximo à letra H, ou seja, várias letras após a letra D, portanto, é considerada "maior que" D.
E estamos
conversados.
Pegue o projeto
aqui:
CShp_CultureStrings.zip
(Porque a vida
foi manifestada, e nós a vimos, e testificamos dela, e vos anunciamos a vida
eterna, que estava com o Pai, e nos foi manifestada);
1 João 1:2
Referências:
VB .NET - Lendo Arquivos Binários - BinaryReader - Macoratti ...
Tratamento de arquivos - Questões práticas - Macoratti.net
C# - Copiando Arquivos - Macoratti
C# - Localizando linhas em um arquivo texto - Macoratti.net
VB .NET - Armazenando um objeto serializado em um arquivo
C# - Programa para Loja de Instrumentos Musicais - Macoratti ...
C# - Lendo e gravando dados binários no SQL ... - Macoratti