it-swarm-fr.com

Quel est généralement le meilleur à utiliser - StringComparison.OrdinalIgnoreCase ou StringComparison.InvariantCultureIgnoreCase?

J'ai un code comme celui-ci:

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

Je me fiche de l'affaire. Dois-je utiliser OrdinalIgnoreCase, InvariantCultureIgnoreCase ou CurrentCultureIgnoreCase?

141
Dave Haynes

Les nouveaux documents .Net ont maintenant un tableau pour vous aider à décider lequel est le mieux à utiliser dans votre situation.

À partir de MSDN " nouvelles recommandations pour l'utilisation de chaînes dans Microsoft .NET 2. "

Résumé: les propriétaires de code qui utilisaient auparavant le InvariantCulture pour la comparaison, la casse et le tri des chaînes devraient sérieusement envisager d'utiliser un nouvel ensemble de surcharges String dans Microsoft .NET 2.0. Plus précisément, les données conçues pour être indépendantes de la culture et non pertinentes sur le plan linguistique devrait commencer à spécifier les surcharges en utilisant le StringComparison.Ordinal ou StringComparison.OrdinalIgnoreCase membres de la nouvelle énumération StringComparison. Ceux-ci appliquent une comparaison octet par octet similaire à strcmp qui évite non seulement les bogues de l'interprétation linguistique des chaînes essentiellement symboliques, mais offre de meilleures performances.

156
Robert Taylor

Tout dépend

La comparaison des chaînes unicode est difficile:

La mise en œuvre de recherches et comparaisons de chaînes Unicode dans un logiciel de traitement de texte doit prendre en compte la présence de points de code équivalents. En l'absence de cette fonctionnalité, les utilisateurs recherchant une séquence de points de code particulière ne pourraient pas trouver d'autres glyphes visuellement indiscernables qui ont une représentation de point de code différente, mais canoniquement équivalente.

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


Si vous essayez de comparer 2 chaînes unicode d'une manière qui ne respecte pas la casse et que cela fonctionne [~ # ~] partout [~ # ~] , vous ont un problème impossible.

L'exemple classique est le turc i , qui en majuscule devient İ (remarquez le point)

Par défaut, le framework .Net utilise généralement CurrentCulture pour les fonctions liées aux chaînes, à une exception très importante de .Equals qui utilise une comparaison ordinale (octet par octet).

Cela conduit, de par leur conception, aux différentes fonctions de chaîne se comportant différemment selon la culture de l'ordinateur.


Néanmoins, nous voulons parfois une comparaison "à usage général", insensible à la casse.

Par exemple, vous pouvez souhaiter que votre comparaison de chaînes se comporte de la même manière, quel que soit l'ordinateur sur lequel votre application est installée.

Pour y parvenir, nous avons 3 options:

  1. Définissez la culture de manière explicite et effectuez une comparaison insensible à la casse à l'aide de règles d'équivalence unicode.
  2. Définissez la culture sur la culture invariante et effectuez une comparaison insensible à la casse en utilisant des règles d'équivalence unicode.
  3. Utilisez OrdinalIgnoreCase qui mettra la chaîne en majuscules à l'aide d'InvariantCulture, puis effectuera une comparaison octet par octet.

Les règles d'équivalence Unicode sont compliquées, ce qui signifie que l'utilisation de la méthode 1) ou 2) est plus coûteuse que OrdinalIgnoreCase. Le fait que OrdinalIgnoreCase n'effectue aucune normalisation unicode spéciale, signifie que certaines chaînes qui s'affichent de la même manière sur un écran d'ordinateur, ne le seront pas seront considérées comme identiques. Par exemple: "\u0061\u030a" et "\u00e5" les deux rendent å. Cependant, une comparaison ordinale sera considérée comme différente.

Ce que vous choisissez dépend fortement de l'application que vous créez.

  • Si j'écrivais une application métier qui n'était utilisée que par des utilisateurs turcs, je serais sûr d'utiliser la méthode 1.
  • Si j'avais juste besoin d'une comparaison "fausse" simple insensible à la casse, par exemple un nom de colonne dans une base de données, qui est généralement l'anglais, j'utiliserais probablement la méthode 3.

Microsoft a son ensemble de recommandations avec des directives explicites. Cependant, il est vraiment important de comprendre la notion d'équivalence unicode avant d'aborder ces problèmes.

Aussi, veuillez garder à l'esprit que OrdinalIgnoreCase est un type très spécial de bête, c'est-à-dire choisir et choisir un peu d'un ordinal par rapport à certains aspects lexicographiques mixtes. Cela peut être déroutant.

57
Sam Saffron

MSDN fait des recommandations assez claires à ce sujet: http://msdn.Microsoft.com/en-us/library/ms973919.aspx

8
chessguy

Je suppose que cela dépend de votre situation. Étant donné que les comparaisons ordinales examinent réellement les valeurs Unicode numériques des caractères, elles ne seront pas le meilleur choix lorsque vous triez par ordre alphabétique. Pour les comparaisons de chaînes, cependant, l'ordinal serait un peu plus rapide.

3
Bullines

Cela dépend de ce que vous voulez, bien que je répugne à la culture invariante à moins que vous ne soyez très sûr de ne jamais vouloir localiser le code pour d'autres langues. Utilisez plutôt CurrentCulture.

En outre, OrdinalIgnoreCase doit respecter les nombres, qui peuvent ou non être ce que vous voulez.

1
Joel Coehoorn

La réponse très simple est que, sauf si vous utilisez le turc, vous n'avez pas besoin d'utiliser InvariantCulture.

Voir le lien suivant:

En C # quelle est la différence entre ToUpper () et ToUpperInvariant ()?

0
TheMoot