it-swarm.it

Qual è generalmente il migliore da usare: StringComparison.OrdinalIgnoreCase o StringComparison.InvariantCultureIgnoreCase?

Ho un codice come questo:

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

Non mi interessa il caso. Dovrei usare OrdinalIgnoreCase, InvariantCultureIgnoreCase o CurrentCultureIgnoreCase?

141
Dave Haynes

I più recenti .Net Docs ora hanno una tabella che ti aiuta a decidere quale è il migliore da usare nella tua situazione.

Da MSDN " Nuovi consigli per l'uso delle stringhe in Microsoft .NET 2. "

Riepilogo: i proprietari di codice che precedentemente utilizzavano InvariantCulture per il confronto di stringhe, il case e l'ordinamento dovrebbero prendere in seria considerazione l'utilizzo di un nuovo set di sovraccarichi String in Microsoft .NET 2.0. In particolare, i dati progettati per essere indipendenti dalla cultura e irrilevanti dal punto di vista linguistico dovrebbero iniziare a specificare i sovraccarichi utilizzando StringComparison.Ordinal o StringComparison.OrdinalIgnoreCase membri della nuova enumerazione StringComparison. Questi impongono un confronto byte per byte simile a strcmp che non solo evita i bug dell'interpretazione linguistica di stringhe essenzialmente simboliche, ma fornisce prestazioni migliori.

156
Robert Taylor

Tutto dipende

Confrontare le stringhe unicode è difficile:

L'implementazione di ricerche e confronti di stringhe Unicode nel software di elaborazione del testo deve tenere conto della presenza di punti di codice equivalenti. In assenza di questa funzione, gli utenti che cercano una particolare sequenza di punti di codice non sarebbero in grado di trovare altri glifi visivamente indistinguibili che hanno una rappresentazione di punti di codice diversa, ma canonicamente equivalente.

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


Se stai cercando di confrontare 2 stringhe unicode in un modo senza distinzione tra maiuscole e minuscole e vuoi che funzioni [~ # ~] ovunque [~ # ~] , avere un problema impossibile.

L'esempio classico è turco i , che quando viene maiuscolo diventa © (notare il punto)

Per impostazione predefinita, il framework .Net di solito utilizza CurrentCulture per le funzioni relative alle stringhe, con un'eccezione molto importante di .Equals che utilizza un confronto ordinale (byte per byte).

Ciò porta, in base alla progettazione, alle varie funzioni di stringa che si comportano in modo diverso a seconda della cultura del computer.


Tuttavia, a volte vogliamo un confronto "generico", senza distinzione tra maiuscole e minuscole.

Ad esempio, è possibile che il confronto delle stringhe si comporti allo stesso modo, indipendentemente dal computer su cui è installata l'applicazione.

Per raggiungere questo obiettivo abbiamo 3 opzioni:

  1. Imposta esplicitamente la cultura ed esegui un confronto senza distinzione tra maiuscole e minuscole utilizzando le regole di equivalenza unicode.
  2. Imposta la cultura su Cultura invariante ed esegui un confronto senza distinzione tra maiuscole e minuscole utilizzando le regole di equivalenza unicode.
  3. Utilizzare OrdinalIgnoreCase che renderà maiuscola la stringa utilizzando InvariantCulture e quindi eseguirà un confronto byte per byte.

Le regole di equivalenza Unicode sono complicate, il che significa che l'utilizzo del metodo 1) o 2) è più costoso di OrdinalIgnoreCase. Il fatto che OrdinalIgnoreCase non esegua alcuna normalizzazione unicode speciale, significa che alcune stringhe che vengono visualizzate allo stesso modo sullo schermo di un computer, non lo faranno saranno considerate identiche. Per esempio: "\u0061\u030a" e "\u00e5" entrambi rendono å. Tuttavia in un confronto ordinale sarà considerato diverso.

La scelta più ampia dipende dall'applicazione che si sta creando.

  • Se stavo scrivendo un'app line-of-business utilizzata solo dagli utenti turchi, sarei sicuro di utilizzare il metodo 1.
  • Se avessi solo bisogno di un semplice confronto "falso" senza distinzione tra maiuscole e minuscole, per esempio un nome di colonna in un db, che di solito è inglese, probabilmente userei il metodo 3.

Microsoft ha il suo set di raccomandazioni con linee guida esplicite. Tuttavia, è davvero importante comprendere la nozione di equivalenza unicode prima di affrontare questi problemi.

Inoltre, tieni presente che OrdinalIgnoreCase è un tipo molto speciale di bestia, che sta raccogliendo e scegliendo un po 'di un confronto ordinale con alcuni aspetti lessicografici misti. Questo può essere fonte di confusione.

57
Sam Saffron

MSDN fornisce alcuni consigli abbastanza chiari su questo: http://msdn.Microsoft.com/en-us/library/ms973919.aspx

8
chessguy

Immagino che dipenda dalla tua situazione. Poiché i confronti ordinali stanno effettivamente osservando i valori numerici Unicode dei caratteri, non saranno la scelta migliore quando si ordina in ordine alfabetico. Per i confronti di stringhe, tuttavia, ordinale sarebbe un po 'più veloce.

3
Bullines

Dipende da cosa vuoi, anche se eviterei la cultura invariante a meno che tu non sia molto sicuro che non vorrai mai localizzare il codice per altre lingue. Utilizzare invece CurrentCulture.

Inoltre, OrdinalIgnoreCase dovrebbe rispettare i numeri, che possono o meno essere ciò che si desidera.

1
Joel Coehoorn

La risposta molto semplice è, a meno che tu non stia usando il turco, non è necessario utilizzare InvariantCulture.

Vedi il seguente link:

In C # qual è la differenza tra ToUpper () e ToUpperInvariant ()?

0
TheMoot