Ce qui est généralement mieux à utiliser - StringComparison.Comparaison OrdinalIgnoreCase ou Stringcomparaison.InvariantCultureIgnoreCase?

j'ai un code comme celui-ci:

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

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

123
demandé sur Arjan Einbu 2008-09-16 18:11:39

6 réponses

à Partir de MSDN " Nouvelles Recommandations pour l'Utilisation des Chaînes de Microsoft .NET 2.0 "

résumé: les propriétaires de Code utilisant précédemment la culture invariante pour la comparaison de chaîne, Le boîtier, et le tri devraient fortement envisager d'utiliser un nouvel ensemble de surcharges de chaîne dans Microsoft .NET 2.0. Plus précisément, les données conçues pour être culturellement agnostiques et linguistiquement non pertinentes devraient commencer à préciser les surcharges en utilisant l'une ou l'autre des méthodes suivantes: StringComparison.Comparaison ordinale ou Stringcomparaison.OrdinalIgnoreCase membres de la nouvelle StringComparison énumération. Ceux-ci imposent une comparaison byte-by-byte similaire à strcmp qui non seulement évite les bugs de l'interprétation linguistique des chaînes essentiellement symboliques, mais fournit de meilleures performances. (15 pages imprimées)

134
répondu Robert Taylor 2008-09-16 14:16:42

tout dépend

comparer les chaînes unicode est difficile:

la mise en œuvre de la chaîne Unicode recherche et comparaison dans le texte logiciel de traitement doit prendre en compte tenu de la présence d'équivalents les points de code. En l'absence de cette fonctionnalité, les utilisateurs à la recherche d'un une séquence particulière de points de code être incapable de trouver d'autres visuellement les glyphes indiscernables qui ont différentes, mais canoniquement équivalent, représentation des points de code.

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


si vous essayez de comparer 2 chaînes unicode d'une manière insensible et que vous voulez qu'il fonctionne partout , vous avez un problème impossible.

l'exemple classique est le Turc i , qui lorsque en majuscules devient I (notez le point)

par défaut, le .net framework utilise habituellement le CurrentCulture pour les fonctions liées aux chaînes, avec une exception très importante de .Equals qui utilise un ordinal (byte by byte) comparer.

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


néanmoins, parfois, nous voulons une "utilisation générale", une comparaison non sensible à la casse.

par exemple, vous pouvez vouloir que votre comparaison de chaîne se comporte de la même manière, peu importe sur quel ordinateur votre application est installée.

pour réaliser ceci nous avons 3 options:

  1. définir explicitement la culture et effectuer une comparaison non sensible à la casse en utilisant des règles d'équivalence unicode.
  2. place la culture à L'Invariant Culture et effectuer une comparaison non sensible à la casse en utilisant les règles d'équivalence unicode.
  3. Utiliser OrdinalIgnoreCase qui sera en majuscule la chaîne à l'aide de la InvariantCulture, puis effectuer 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 de caractères qui rendent de la même manière sur un écran d'ordinateur, ne seront pas seront considérées comme identiques. Par exemple: "\u0061\u030a" et "\u00e5" rendent tous deux å. Toutefois, dans une comparaison ordinale sera considérée différente.

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

  • si j'écrivais une application de ligne-of-business qui a été utilisé seulement par les utilisateurs turcs, je serais sûr d'utiliser méthode 1.
  • si j'avais juste besoin d'un simple" faux " cas insensible comparer, pour dire un nom de colonne dans un db, qui est habituellement anglais, je voudrais probablement utiliser la méthode 3.

Microsoft a son ensemble de recommandations avec des lignes directrices explicites. Toutefois, il est très important de comprendre la notion d'équivalence unicode avant d'aborder ces problèmes.

aussi, s'il vous plaît gardez à l'esprit cette OrdinalIgnoreCase est un genre très spécial de bête, c'est-à-dire la cueillette et le choix d'un peu d'un ordinal comparer avec certains mélangé dans les aspects lexicographiques. Cela peut être source de confusion.

51
répondu Sam Saffron 2014-10-08 17:07:09

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

8
répondu chessguy 2008-09-16 14:13:41

ça dépend de votre situation. Puisque les comparaisons ordinales sont en fait en train de regarder les valeurs numériques Unicode des caractères, ils ne seront pas le meilleur choix quand vous triez par ordre alphabétique. Pour comparer les chaînes, ordinal serait un peu plus rapide.

3
répondu Bullines 2008-09-16 14:17:22

cela dépend de ce que vous voulez, bien que j'éviterais la culture invariante à moins que vous ne soyez très sûr que vous ne voudrez jamais localiser le code pour d'autres langues. Utilisation CurrentCulture à la place.

en outre, OrdinalIgnoreCase devrait respecter les nombres, qui peuvent ou ne peuvent pas être ce que vous voulez.

1
répondu Joel Coehoorn 2008-09-16 14:13:00

la réponse est très simple, sauf si vous utilisez le turc, vous n'avez pas besoin d'utiliser la culture invariante.

voir le lien suivant:

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

0
répondu TheMoot 2017-05-23 12:34:20