Was ist der Unterschied zwischen InvariantCulture und Ordinal-Vergleich beim Vergleich zweier Strings in c# auf Gleichheit?
Antworten
Zu viele Anzeigen?UnveränderlicheKultur
Verwendet einen "Standard"-Satz von Zeichenreihenfolgen (a,b,c, ... usw.). Dies steht im Gegensatz zu einigen spezifischen Gebietsschemata, die Zeichen in unterschiedlicher Reihenfolge sortieren können ("a-mit-akut" kann vor ou nach 'a', je nach Gebietsschema, usw.).
Ordinal
Andererseits werden nur die Werte der Rohbytes betrachtet, die das Zeichen darstellen.
Ein tolles Beispiel finden Sie unter http://msdn.microsoft.com/en-us/library/e6883c06.aspx die die Ergebnisse der verschiedenen StringComparison-Werte anzeigt. Ganz am Ende zeigt es (auszugsweise):
StringComparison.InvariantCulture:
LATIN SMALL LETTER I (U+0069) is less than LATIN SMALL LETTER DOTLESS I (U+0131)
LATIN SMALL LETTER I (U+0069) is less than LATIN CAPITAL LETTER I (U+0049)
LATIN SMALL LETTER DOTLESS I (U+0131) is greater than LATIN CAPITAL LETTER I (U+0049)
StringComparison.Ordinal:
LATIN SMALL LETTER I (U+0069) is less than LATIN SMALL LETTER DOTLESS I (U+0131)
LATIN SMALL LETTER I (U+0069) is greater than LATIN CAPITAL LETTER I (U+0049)
LATIN SMALL LETTER DOTLESS I (U+0131) is greater than LATIN CAPITAL LETTER I (U+0049)
Wie Sie sehen, ergibt InvariantCulture (U+0069, U+0049, U+00131), Ordinal (U+0049, U+0069, U+00131).
Zeigen auf Bewährte Praktiken für die Verwendung von Strings im .NET Framework :
- Verwenden Sie
StringComparison.Ordinal
oStringComparison.OrdinalIgnoreCase
für Vergleiche als sichere Vorgabe für kulturunabhängigen Zeichenfolgenabgleich. - Verwenden Sie Vergleiche mit
StringComparison.Ordinal
oStringComparison.OrdinalIgnoreCase
für eine bessere Leistung. - Verwenden Sie die nichtsprachlichen
StringComparison.Ordinal
oStringComparison.OrdinalIgnoreCase
Werte anstelle von String-Operationen auf der Grundlage vonCultureInfo.InvariantCulture
wenn der Vergleich sprachlich irrelevant ist (z. B. symbolisch).
Und schließlich:
- Verwenden Sie keine String-Operationen, die auf
StringComparison.InvariantCulture
in den meisten Fällen . Eine der wenigen Ausnahmen besteht dann, wenn Sie sprachlich bedeutsame, aber kulturell agnostische Daten aufbewahren.
Ein weiterer praktischer Unterschied (im Englischen, wo Akzente unüblich sind) ist, dass ein InvariantCulture-Vergleich die gesamte Zeichenkette zunächst ohne Berücksichtigung der Groß- und Kleinschreibung vergleicht und dann, falls erforderlich (und gewünscht), nach Groß- und Kleinschreibung unterscheidet, nachdem zunächst nur die einzelnen Buchstaben verglichen wurden. (Sie können natürlich auch einen case-insensitive-Vergleich durchführen, bei dem nicht nach Groß- und Kleinschreibung unterschieden wird). Korrigiert: Buchstaben mit Akzent werden als eine andere Variante derselben Buchstaben betrachtet, und die Zeichenkette wird verglichen, wobei die Akzente zunächst ignoriert und dann berücksichtigt werden, wenn die allgemeinen Buchstaben alle übereinstimmen (ähnlich wie bei der unterschiedlichen Groß- und Kleinschreibung, nur dass sie bei einem Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung letztlich nicht ignoriert werden). Auf diese Weise werden akzentuierte Versionen des ansonsten gleichen Wortes nebeneinander gruppiert, anstatt beim ersten Akzentunterschied komplett getrennt zu werden. Dies ist die Sortierreihenfolge, die Sie typischerweise in einem Wörterbuch finden, wobei großgeschriebene Wörter direkt neben ihren klein geschriebenen Äquivalenten erscheinen und akzentuierte Buchstaben in der Nähe des entsprechenden unakzentuierten Buchstabens stehen.
Bei einem ordinalen Vergleich werden ausschließlich die numerischen Zeichenwerte verglichen, wobei bei der ersten Differenz angehalten wird. Dadurch werden Großbuchstaben völlig getrennt von Kleinbuchstaben sortiert (und Akzentbuchstaben vermutlich getrennt von diesen), so dass großgeschriebene Wörter nicht in der Nähe ihrer Kleinbuchstaben-Äquivalente sortiert werden.
InvariantCulture betrachtet auch Großbuchstaben als größer als Kleinbuchstaben, während Ordinal Großbuchstaben als kleiner als Kleinbuchstaben betrachtet (ein Überbleibsel von ASCII aus den alten Tagen, als Computer noch keine Kleinbuchstaben hatten, die Großbuchstaben wurden zuerst zugewiesen und hatten daher niedrigere Werte als die später hinzugefügten Kleinbuchstaben).
Zum Beispiel durch Ordinal: "0" < "9" < "A" < "Ab" < "Z" < "a" < "aB" < "ab" < "z" < "Á" < "Áb" < "á" < "áb"
Und von InvariantCulture: "0" < "9" < "a" < "A" < "á" < "Á" < "ab" < "aB" < "Ab" < "áb" < "Áb" < "z" < "Z"
Obwohl die Frage sich auf Gleichstellung Für eine schnelle visuelle Referenz, hier die Reihenfolge einiger Strings sortiert anhand einiger Kulturen, die einige der dortigen Eigenheiten veranschaulichen.
Ordinal 0 9 A Ab a aB aa ab ss Ä Äb ß ä äb
IgnoreCase 0 9 a A aa ab Ab aB ss ä Ä äb Äb ß
--------------------------------------------------------------------
InvariantCulture 0 9 a A ä Ä aa ab aB Ab äb Äb ss ß
IgnoreCase 0 9 A a Ä ä aa Ab aB ab Äb äb ß ss
--------------------------------------------------------------------
da-DK 0 9 a A ab aB Ab ss ß ä Ä äb Äb aa
IgnoreCase 0 9 A a Ab aB ab ß ss Ä ä Äb äb aa
--------------------------------------------------------------------
de-DE 0 9 a A ä Ä aa ab aB Ab äb Äb ß ss
IgnoreCase 0 9 A a Ä ä aa Ab aB ab Äb äb ss ß
--------------------------------------------------------------------
en-US 0 9 a A ä Ä aa ab aB Ab äb Äb ß ss
IgnoreCase 0 9 A a Ä ä aa Ab aB ab Äb äb ss ß
--------------------------------------------------------------------
ja-JP 0 9 a A ä Ä aa ab aB Ab äb Äb ß ss
IgnoreCase 0 9 A a Ä ä aa Ab aB ab Äb äb ss ß
Beobachtungen:
de-DE
,ja-JP
yen-US
auf die gleiche Weise sortierenInvariant
sortiert nurss
yß
anders als die drei oben genannten Kulturenda-DK
sortiert ganz anders- die
IgnoreCase
Kennzeichen für alle beprobten Kulturen
Der Code, der zur Erstellung der obigen Tabelle verwendet wurde:
var l = new List<string>
{ "0", "9", "A", "Ab", "a", "aB", "aa", "ab", "ss", "ß",
"Ä", "Äb", "ä", "äb", "", "", "", "", "", "" };
foreach (var comparer in new[]
{
StringComparer.Ordinal,
StringComparer.OrdinalIgnoreCase,
StringComparer.InvariantCulture,
StringComparer.InvariantCultureIgnoreCase,
StringComparer.Create(new CultureInfo("da-DK"), false),
StringComparer.Create(new CultureInfo("da-DK"), true),
StringComparer.Create(new CultureInfo("de-DE"), false),
StringComparer.Create(new CultureInfo("de-DE"), true),
StringComparer.Create(new CultureInfo("en-US"), false),
StringComparer.Create(new CultureInfo("en-US"), true),
StringComparer.Create(new CultureInfo("ja-JP"), false),
StringComparer.Create(new CultureInfo("ja-JP"), true),
})
{
l.Sort(comparer);
Console.WriteLine(string.Join(" ", l));
}
- See previous answers
- Weitere Antworten anzeigen
0 Stimmen
Vielleicht siao2.com/2004/12/29/344136.aspx ? (gegoogelt)
3 Stimmen
Für diejenigen, die
String1.Equals(String2, StringComparison.Ordinal)
verwenden Sie besserString1 == String2
die von Haus ausString1.Equals(String2)
und ist standardmäßig ein ordinaler Vergleich unter Berücksichtigung der Groß- und Kleinschreibung.3 Stimmen
@Ghasan Ich bin nicht sicher, ob das etwas bringt.
==
"besser", aber er ist a) kürzer, b) weniger eindeutig in Bezug auf seine genaue Funktion und c)String1
Null sein kann, ohne dass der Vergleich einNullReferenceException
.5 Stimmen
@Ghasan der offizielle MSDN Bewährte Praktiken für die Verwendung von Strings im .NET Framework Seite ( msdn.microsoft.com/de-us/library/ ) empfiehlt die Verwendung von Überladungen, die explizit die
StringComparison
Typ. Im Falle des String-Vergleichs bedeutet diesString.Equals
.3 Stimmen
@EugeneBeresovsky Zu vermeiden
NullReferenceException
können Sie einfach die statische Methode verwenden:String.Equals(string1, string2, StringComparison.Ordinal)
.