it-swarm-pt.tech

O que geralmente é melhor usar - StringComparison.OrdinalIgnoreCase ou StringComparison.InvariantCultureIgnoreCase?

Eu tenho algum código como este:

If key.Equals("search", StringComparison.OrdinalIgnoreCase) Then
    DoSomething()
End If

Eu não ligo para o caso. Devo usar OrdinalIgnoreCase, InvariantCultureIgnoreCase ou CurrentCultureIgnoreCase?

141
Dave Haynes

O .Net Docs mais recente agora tem uma tabela para ajudá-lo a decidir qual é o melhor para usar em sua situação.

Do MSDN " Novas recomendações para usar seqüências de caracteres no Microsoft .NET 2. "

Resumo: Os proprietários de código que anteriormente utilizavam InvariantCulture para comparação, classificação e classificação de cadeias de caracteres devem considerar o uso de um novo conjunto de sobrecargas String no Microsoft .NET 2.0. Especificamente, os dados projetados para serem independentes da cultura e linguisticamente irrelevantes devem começar a especificar sobrecargas usando os membros StringComparison.Ordinal ou StringComparison.OrdinalIgnoreCase dos novos StringComparison enumeração. Eles impõem uma comparação de byte a byte semelhante a strcmp que não apenas evita bugs da interpretação linguística de seqüências essencialmente simbólicas, mas fornece melhor desempenho.

156
Robert Taylor

Tudo depende

Comparar strings unicode é difícil:

A implementação de pesquisas e comparações de cadeias Unicode no software de processamento de texto deve levar em consideração a presença de pontos de código equivalentes. Na ausência desse recurso, os usuários que procuram uma sequência de pontos de código específica não conseguiriam encontrar outros glifos visualmente indistinguíveis que tenham uma representação de ponto de código diferente, mas canonicamente equivalente.

veja: http://en.wikipedia.org/wiki/Unicode_equivalence


Se você está tentando comparar duas cadeias unicode de uma maneira que não diferencia maiúsculas de minúsculas e deseja que funcione EM TODOS OS LUGARES, você tem um problema impossível.

O exemplo clássico é o turco i , que quando maiúsculo se torna © (observe o ponto)

Por padrão, a estrutura .Net geralmente usa o CurrentCulture para funções relacionadas a cadeias, com uma exceção muito importante de .Equals que usa uma comparação ordinal (byte por byte).

Isso leva, por design, às várias funções de string que se comportam de maneira diferente, dependendo da cultura do computador.


No entanto, às vezes queremos uma comparação de "uso geral", sem distinção entre maiúsculas e minúsculas.

Por exemplo, você pode querer que sua comparação de cadeias se comporte da mesma maneira, não importa em que computador seu aplicativo esteja instalado.

Para conseguir isso, temos 3 opções:

  1. Defina a cultura explicitamente e faça uma comparação sem distinção entre maiúsculas e minúsculas usando regras de equivalência unicode.
  2. Defina a cultura como Cultura invariável e execute comparação sem distinção entre maiúsculas e minúsculas usando regras de equivalência unicode.
  3. Use OrdinalIgnoreCase , que colocará em maiúsculas a string usando o InvariantCulture e, em seguida, executará uma comparação de byte a byte.

As regras de equivalência Unicode são complicadas, o que significa que o método 1) ou 2) é mais caro que OrdinalIgnoreCase. O fato de OrdinalIgnoreCase não executar nenhuma normalização unicode especial significa que algumas seqüências que são renderizadas da mesma maneira na tela do computador não serão consideradas idênticas. Por exemplo: "\u0061\u030a" e "\u00e5" ambos processam å. No entanto, em uma comparação ordinal será considerado diferente.

A escolha que você escolher depende muito do aplicativo que você está criando.

  • Se eu estivesse escrevendo um aplicativo de linha de negócios usado apenas por usuários turcos, certamente usaria o método 1.
  • Se eu apenas precisasse de uma comparação simples e sem distinção entre maiúsculas e minúsculas, por exemplo, um nome de coluna em um banco de dados, que geralmente é inglês, provavelmente usaria o método 3.

A Microsoft possui seu conjunto de recomendações com diretrizes explícitas. No entanto, é realmente importante entender a noção de equivalência unicode antes de abordar esses problemas.

Além disso, lembre-se de que OrdinalIgnoreCase é um tipo muito especial de animal, que está escolhendo e escolhendo um pouco de um ordinal comparado com alguns misturados em aspectos lexicográficos. Isso pode ser confuso.

57
Sam Saffron

O MSDN faz algumas recomendações bem claras sobre isso: http://msdn.Microsoft.com/en-us/library/ms973919.aspx

8
chessguy

Eu acho que depende da sua situação. Como as comparações ordinais estão de fato observando os valores numéricos Unicode dos caracteres, elas não serão a melhor opção quando você estiver classificando em ordem alfabética. Para comparações de strings, ordinal seria um pouco mais rápido.

3
Bullines

Depende do que você deseja, embora eu evite a cultura invariável, a menos que você tenha muito certeza de que nunca deseja localizar o código para outros idiomas. Use CurrentCulture.

Além disso, OrdinalIgnoreCase deve respeitar os números, que podem ou não ser o que você deseja.

1
Joel Coehoorn

A resposta muito simples é que, a menos que você esteja usando turco, não precisará usar o InvariantCulture.

Veja o seguinte link:

Em C #, qual é a diferença entre ToUpper () e ToUpperInvariant ()?

0
TheMoot