Ao comparar duas seqüências de caracteres em c # para igualdade, qual é a diferença entre comparação entre InvariantCulture e Ordinal?
c#
.net
string-comparison
ordinal
Kapil
fonte
fonte
String1.Equals(String2, StringComparison.Ordinal)
, é melhor usar oString1 == String2
que é intrinsecamenteString1.Equals(String2)
e, por padrão, é uma comparação ordinal que diferencia maiúsculas de minúsculas.==
"melhora", mas é a) mais curto, b) menos explícito sobre o que exatamente ele faz e c)String1
pode ser nulo sem a comparação de aNullReferenceException
.StringComparison
tipo. No caso de comparação de strings, isso significaString.Equals
.NullReferenceException
que você pode simplesmente usar o método estático:String.Equals(string1, string2, StringComparison.Ordinal)
.Respostas:
InvariantCulture
Usa um conjunto "padrão" de ordenação de caracteres (a, b, c, ... etc.). Isso contrasta com algumas localidades específicas, que podem classificar caracteres em diferentes ordens ('a-with-aguda' pode ser antes ou depois de 'a', dependendo da localidade e assim por diante).
Ordinal
Por outro lado, analisa puramente os valores dos bytes brutos que representam o caractere.
Há um ótimo exemplo em http://msdn.microsoft.com/en-us/library/e6883c06.aspx que mostra os resultados dos vários valores de StringComparison. No final, ele mostra (trecho):
Você pode ver que, onde InvariantCulture gera (U + 0069, U + 0049, U + 00131), Ordinal produz (U + 0049, U + 0069, U + 00131).
fonte
Importa, por exemplo - existe uma coisa chamada expansão de personagem
Com
InvariantCulture
o caractere ß é expandido para ss.fonte
Ordinal
eInvariantCulture
? É disso que trata a pergunta original.ß
, deve-se notar queß
pelo menos em alemão é igual a um s duplo, Fonte: en.wikipedia.org/wiki/%C3%9Fß
ess
alternadamente em alemão (eu sou um falante nativo). Existem casos em que ambos são legais (mas geralmente um está desatualizado / não é recomendado) e há casos em que apenas um formulário é permitido.Apontando para as práticas recomendadas para usar seqüências de caracteres no .NET Framework :
StringComparison.Ordinal
ouStringComparison.OrdinalIgnoreCase
para comparações como seu padrão seguro para correspondência de sequência independente de cultura.StringComparison.Ordinal
ouStringComparison.OrdinalIgnoreCase
para obter melhor desempenho.StringComparison.Ordinal
ou emStringComparison.OrdinalIgnoreCase
vez das operações de cadeia de caracteres com base emCultureInfo.InvariantCulture
quando a comparação for linguisticamente irrelevante (simbólica, por exemplo).E finalmente:
StringComparison.InvariantCulture
na maioria dos casos . Uma das poucas exceções é quando você persiste em dados lingüisticamente significativos, mas culturalmente agnósticos.fonte
Outra diferença útil (em inglês, onde os acentos são incomuns) é que uma comparação da InvariantCulture compara as seqüências inteiras primeiro sem distinção entre maiúsculas e minúsculas e, em seguida, se necessário (e solicitado) distingue por maiúsculas e minúsculas depois de comparar primeiro apenas nas letras distintas. (Você também pode fazer uma comparação sem distinção entre maiúsculas e minúsculas, é claro, o que não fará distinção entre maiúsculas e minúsculas.) Corrigido:As letras acentuadas são consideradas outro sabor das mesmas letras e a cadeia de caracteres é comparada primeiro, ignorando os acentos e depois contabilizando-os se todas as letras gerais corresponderem (da mesma forma que em maiúsculas e minúsculas, exceto que, no final, não são ignoradas em uma comparação que não diferencia maiúsculas de minúsculas). Isso agrupa versões acentuadas da mesma palavra, próximas umas das outras, em vez de se separarem completamente na primeira diferença de sotaque. Essa é a ordem de classificação que você normalmente encontraria em um dicionário, com palavras em maiúsculas aparecendo ao lado de seus equivalentes em minúsculas e letras acentuadas próximas à letra não acentuada correspondente.
Uma comparação ordinal compara estritamente os valores numéricos dos caracteres, parando na primeira diferença. Isso classifica as letras maiúsculas completamente separadas das letras minúsculas (e as letras acentuadas provavelmente se separam daquelas), para que as palavras maiúsculas não se aproximem dos equivalentes em minúsculas.
InvariantCulture também considera maiúsculas maiúsculas e minúsculas, enquanto Ordinal considera maiúsculas minúsculas (uma recuperação de ASCII dos velhos tempos antes dos computadores terem letras minúsculas, as letras maiúsculas eram alocadas primeiro e, portanto, tinham valores inferiores às letras minúsculas adicionado mais tarde).
Por exemplo, por Ordinal:
"0" < "9" < "A" < "Ab" < "Z" < "a" < "aB" < "ab" < "z" < "Á" < "Áb" < "á" < "áb"
E por InvariantCulture:
"0" < "9" < "a" < "A" < "á" < "Á" < "ab" < "aB" < "Ab" < "áb" < "Áb" < "z" < "Z"
fonte
Embora a questão seja sobre igualdade , para referência visual rápida, aqui está a ordem de algumas sequências ordenadas usando algumas culturas que ilustram algumas das idiossincrasias por aí.
Observações:
de-DE
,ja-JP
een-US
classifique da mesma maneiraInvariant
apenas classificass
eß
diferentemente das três culturas acimada-DK
classifica de maneira bem diferenteIgnoreCase
bandeira é importante para todas as culturas incluídas na amostraO código usado para gerar a tabela acima:
fonte
CultureComparer
que poderíamos usar Para esta tabela, aDanish
cultura (informações) acabou sendo muito importante.)Invariante é um tipo de comparação linguisticamente apropriado.
Ordinal é um tipo binário de comparação. (mais rápido)
Consulte http://www.siao2.com/2004/12/29/344136.aspx
fonte
Aqui está um exemplo em que a comparação de igualdade de string usando InvariantCultureIgnoreCase e OrdinalIgnoreCase não fornecerá os mesmos resultados:
Se você executar isso, igual a 1 será falso e igual a 2 será verdadeiro.
fonte
a="\x00e9"
(e aguda) eb="\x0065\x0301"
(e combinadas com um acento agudo),StringComparer.Ordinal.Equals(a, b)
retornará falso enquantoStringComparer.InvariantCulture.Equals(a, b)
retornará verdadeiro.Não é necessário usar exemplos sofisticados de caracteres unicode para mostrar a diferença. Aqui está um exemplo simples que descobri hoje que é surpreendente, consistindo apenas em caracteres ASCII.
De acordo com a tabela ASCII,
0
(0x48) é menor que_
(0x95) quando comparado ordinalmente. InvariantCulture diria o contrário (código do PowerShell abaixo):fonte
Sempre tente usar InvariantCulture nos métodos de string que o aceitam como sobrecarga. Usando InvariantCulture, você está em um lado seguro. Muitos programadores .NET podem não usar essa funcionalidade, mas se o seu software for usado por diferentes culturas, o InvariantCulture é um recurso extremamente útil.
fonte