Lorsque vous comparez deux chaînes en c # pour l'égalité, quelle est la différence entre InvariantCulture et la comparaison ordinale?
c#
.net
string-comparison
ordinal
Kapil
la source
la source
String1.Equals(String2, StringComparison.Ordinal)
, il vaut mieux utiliserString1 == String2
ce qui est intrinsèquementString1.Equals(String2)
et c'est par défaut une comparaison ordinale sensible à la casse.==
"mieux", mais c'est a) plus court, b) moins explicite sur ce qu'il fait exactement et c)String1
peut être nul sans que la comparaison ne lance aNullReferenceException
.StringComparison
type. Dans le cas de la comparaison de chaînes, cela signifieString.Equals
.NullReferenceException
vous pouvez simplement utiliser la méthode statique:String.Equals(string1, string2, StringComparison.Ordinal)
.Réponses:
InvariantCulture
Utilise un ensemble "standard" d'ordonnances de caractères (a, b, c, ... etc.). Cela contraste avec certains paramètres régionaux spécifiques, qui peuvent trier les caractères dans des ordres différents («a-with-aigu» peut être avant ou après «a», selon les paramètres régionaux, etc.).
Ordinal
D'un autre côté, regarde uniquement les valeurs des octets bruts qui représentent le caractère.
Il existe un excellent exemple à http://msdn.microsoft.com/en-us/library/e6883c06.aspx qui montre les résultats des différentes valeurs StringComparison. À la fin, cela montre (extrait):
Vous pouvez voir que lorsque InvariantCulture donne (U + 0069, U + 0049, U + 00131), les rendements ordinaux (U + 0049, U + 0069, U + 00131).
la source
Cela importe, par exemple - il y a une chose appelée expansion des personnages
Le
InvariantCulture
caractère ß est étendu aux ss.la source
Ordinal
etInvariantCulture
? C'est de cela qu'il s'agit à l'origine.ß
il convient de noter qu'auß
moins en allemand équivaut à un double s, Source: en.wikipedia.org/wiki/%C3%9Fß
et dess
manière interchangeable en allemand (je suis un locuteur natif). Il y a des cas où les deux sont légaux (mais souvent l'un est obsolète / déconseillé) et il y a des cas où un seul formulaire est autorisé.Pointant vers les meilleures pratiques pour l'utilisation de chaînes dans le .NET Framework :
StringComparison.Ordinal
ouStringComparison.OrdinalIgnoreCase
pour les comparaisons comme valeur par défaut pour la correspondance de chaînes indépendante de la culture.StringComparison.Ordinal
ouStringComparison.OrdinalIgnoreCase
pour de meilleures performances.StringComparison.Ordinal
ouStringComparison.OrdinalIgnoreCase
au lieu d'opérations de chaîne en fonction duCultureInfo.InvariantCulture
moment où la comparaison n'est pas pertinente sur le plan linguistique (symbolique, par exemple).Et enfin:
StringComparison.InvariantCulture
dans la plupart des cas . L'une des rares exceptions concerne les données persistantes sur le plan linguistique mais culturellement agnostiques.la source
Une autre différence pratique (en anglais où les accents sont rares) est qu'une comparaison InvariantCulture compare d'abord les chaînes entières en respectant la casse, puis si nécessaire (et demandé) distingue par cas après avoir d'abord comparé uniquement sur les lettres distinctes. (Vous pouvez également faire une comparaison insensible à la casse, bien sûr, qui ne distingue pas par cas.) Corrigé:Les lettres accentuées sont considérées comme une autre saveur des mêmes lettres et la chaîne est d'abord comparée en ignorant les accents, puis en les comptabilisant si les lettres générales correspondent toutes (tout comme avec une casse différente, mais pas finalement ignorée dans une comparaison insensible à la casse). Cela regroupe les versions accentuées du même mot autrement près les unes des autres au lieu d'être complètement séparées à la première différence d'accent. Il s'agit de l'ordre de tri que vous trouverez généralement dans un dictionnaire, avec des mots en majuscule apparaissant juste à côté de leurs équivalents en minuscules et des lettres accentuées proches de la lettre non accentuée correspondante.
Une comparaison ordinale compare strictement les valeurs des caractères numériques, s'arrêtant à la première différence. Cela trie les lettres majuscules complètement distinctes des lettres minuscules (et les lettres accentuées vraisemblablement distinctes de celles-ci), de sorte que les mots en majuscules ne seraient nulle part proches de leurs équivalents minuscules.
InvariantCulture considère également que les majuscules sont plus grandes que les minuscules, alors que Ordinal considère les majuscules moins que les minuscules (une trace d'ASCII de l'ancien temps avant que les ordinateurs aient des lettres minuscules, les lettres majuscules étaient allouées en premier et avaient donc des valeurs inférieures aux lettres minuscules). ajouté plus tard).
Par exemple, par Ordinal:
"0" < "9" < "A" < "Ab" < "Z" < "a" < "aB" < "ab" < "z" < "Á" < "Áb" < "á" < "áb"
Et par InvariantCulture:
"0" < "9" < "a" < "A" < "á" < "Á" < "ab" < "aB" < "Ab" < "áb" < "Áb" < "z" < "Z"
la source
Bien que la question porte sur l' égalité , pour une référence visuelle rapide, voici l'ordre de certaines chaînes triées à l' aide de deux cultures illustrant certaines des idiosyncrasies là-bas.
Observations:
de-DE
,ja-JP
Eten-US
sorte de la même façonInvariant
trie seulementss
etß
différemment des trois cultures ci-dessusda-DK
trie très différemmentIgnoreCase
drapeau est important pour toutes les cultures échantillonnéesLe code utilisé pour générer le tableau ci-dessus:
la source
CultureComparer
que nous pourrions utiliser Pour vérifier ce tableau, laDanish
culture (info) s'est avérée très importante.)Invariant est un type de comparaison linguistiquement approprié.
Ordinal est un type de comparaison binaire. (plus rapide)
Voir http://www.siao2.com/2004/12/29/344136.aspx
la source
Voici un exemple où la comparaison d'égalité de chaîne utilisant InvariantCultureIgnoreCase et OrdinalIgnoreCase ne donnera pas les mêmes résultats:
Si vous exécutez ceci, equals1 sera faux et equals2 sera vrai.
la source
a="\x00e9"
(e aigu) etb="\x0065\x0301"
(e combiné avec un accent aigu),StringComparer.Ordinal.Equals(a, b)
renverra faux tandis queStringComparer.InvariantCulture.Equals(a, b)
reviendra vrai.Pas besoin d'utiliser des exemples de caractères unicode fantaisie pour montrer la différence. Voici un exemple simple que j'ai découvert aujourd'hui qui est surprenant, composé uniquement de caractères ASCII.
Selon le tableau ASCII,
0
(0x48) est plus petit que_
(0x95) en comparaison ordinaire. InvariantCulture dirait le contraire (code PowerShell ci-dessous):la source
Essayez toujours d'utiliser InvariantCulture dans les méthodes de chaîne qui l'acceptent comme surcharge. En utilisant InvariantCulture, vous êtes du bon côté. De nombreux programmeurs .NET peuvent ne pas utiliser cette fonctionnalité, mais si votre logiciel sera utilisé par différentes cultures, InvariantCulture est une fonctionnalité extrêmement pratique.
la source