Welches ist im Allgemeinen am besten zu verwenden - StringComparison.OrdinalIgnoreCase oder StringComparison.InvariantCultureIgnoreCase?

161

Ich habe einen Code wie diesen:

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

Der Fall ist mir egal. Soll ich OrdinalIgnoreCase, InvariantCultureIgnoreCaseoder CurrentCultureIgnoreCase?

Dave Haynes
quelle
2
Überprüfen Sie, ob dies für diesen Thread wirklich nützlich ist. Mein Vorschlag, ordianlignorecase zum Vergleich zu verwenden. blogs.msdn.com/b/noahc/archive/2007/06/29/…
UmaMaheswaran
Betrachten Sie die hoch bewertete
Michael Freidgeim
Insgesamt hängt es sehr davon ab, was Sie vergleichen. Insbesondere, wenn es sich um kulturabhängige Benutzereingaben oder interne Inhalte handelt. Sie möchten nicht, dass die Kultur des PCs interne Code-String-Vergleiche durcheinander bringt.
Nyerguds

Antworten:

179

Neuere .Net Docs verfügen jetzt über eine Tabelle, anhand derer Sie entscheiden können, welche in Ihrer Situation am besten geeignet ist.

Aus MSDNs " Neue Empfehlungen für die Verwendung von Zeichenfolgen in Microsoft .NET 2.0 "

Zusammenfassung: Codebesitzer, die zuvor die InvariantCultureOption zum Vergleichen, Umschließen und Sortieren von Zeichenfolgen verwenden, sollten die Verwendung neuer StringÜberladungen in Microsoft .NET 2.0 in Betracht ziehen . Insbesondere sollten Daten, die kulturunabhängig und sprachlich irrelevant sind, Überladungen angeben, indem sie entweder die StringComparison.Ordinaloder die StringComparison.OrdinalIgnoreCaseMitglieder der neuen StringComparisonAufzählung verwenden. Diese erzwingen einen ähnlichen Byte-für-Byte-Vergleich strcmp, der nicht nur Fehler bei der sprachlichen Interpretation von im Wesentlichen symbolischen Zeichenfolgen vermeidet, sondern auch eine bessere Leistung bietet.

Robert Taylor
quelle
126
Um ein Beispiel zu geben, in dem sie sich unterscheiden, betrachten Sie die beiden Zeichenfolgen "Straße"und "STRASSE". Bei der Verwendung OrdinalIgnoreCaseder EqualsRetouren false, während InvariantCultureIgnoreCasesagt , dass sie gleich sind.
Jeppe Stig Nielsen
2
Aktualisierter Link: docs.microsoft.com/en-us/dotnet/standard/base-types/…
Ohad Schneider
63

Es hängt alles ab

Der Vergleich von Unicode-Zeichenfolgen ist schwierig:

Bei der Implementierung von Unicode-Zeichenfolgensuchen und -vergleichen in Textverarbeitungssoftware müssen gleichwertige Codepunkte berücksichtigt werden. Ohne diese Funktion könnten Benutzer, die nach einer bestimmten Codepunktsequenz suchen, keine anderen visuell nicht unterscheidbaren Glyphen finden, die eine andere, aber kanonisch äquivalente Codepunktdarstellung aufweisen.

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


Wenn Sie versuchen, 2 Unicode-Zeichenfolgen ohne Berücksichtigung der Groß- und Kleinschreibung zu vergleichen und möchten, dass sie ÜBERALL funktionieren , haben Sie ein unmögliches Problem.

Das klassische Beispiel ist das türkische i , das in Großbuchstaben zu İ wird (beachten Sie den Punkt).

Standardmäßig verwendet das .Net-Framework die CurrentCulture für Zeichenfolgenfunktionen, mit einer sehr wichtigen Ausnahme .Equals, bei der ein Ordnungsvergleich (Byte für Byte) verwendet wird.

Dies führt konstruktionsbedingt dazu, dass sich die verschiedenen Zeichenfolgenfunktionen je nach Computerkultur unterschiedlich verhalten.


Trotzdem wollen wir manchmal einen "allgemeinen Zweck", bei dem die Groß- und Kleinschreibung nicht berücksichtigt wird.

Beispielsweise möchten Sie möglicherweise, dass sich Ihr Zeichenfolgenvergleich unabhängig vom Computer, auf dem Ihre Anwendung installiert ist, genauso verhält.

Um dies zu erreichen, haben wir 3 Möglichkeiten:

  1. Stellen Sie die Kultur explizit ein und führen Sie einen Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung mithilfe von Unicode-Äquivalenzregeln durch.
  2. Stellen Sie die Kultur auf Invariante Kultur ein und führen Sie einen Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung mithilfe von Unicode-Äquivalenzregeln durch.
  3. Verwenden Sie OrdinalIgnoreCase, bei dem die Zeichenfolge mithilfe der InvariantCulture in Großbuchstaben geschrieben wird, und führen Sie dann einen byteweisen Vergleich durch.

Unicode-Äquivalenzregeln sind kompliziert, was bedeutet, dass die Verwendung von Methode 1) oder 2) teurer ist als OrdinalIgnoreCase. Die Tatsache, dass OrdinalIgnoreCasekeine spezielle Unicode-Normalisierung durchgeführt wird, bedeutet, dass einige Zeichenfolgen, die auf einem Computerbildschirm auf dieselbe Weise gerendert werden, nicht als identisch angesehen werden. Zum Beispiel: "\u0061\u030a"und "\u00e5"beide rendern å. Bei einem Ordnungsvergleich wird dies jedoch als unterschiedlich angesehen.

Welche Sie stark auswählen, hängt von der Anwendung ab, die Sie erstellen.

  • Wenn ich eine Branchen-App schreiben würde, die nur von türkischen Benutzern verwendet wird, würde ich sicher Methode 1 verwenden.
  • Wenn ich nur einen einfachen "falschen" Vergleich ohne Berücksichtigung der Groß- und Kleinschreibung benötige, zum Beispiel einen Spaltennamen in einer Datenbank, der normalerweise Englisch ist, würde ich wahrscheinlich Methode 3 verwenden.

Microsoft hat seine Empfehlungen mit expliziten Richtlinien. Es ist jedoch sehr wichtig, den Begriff der Unicode-Äquivalenz zu verstehen, bevor diese Probleme angegangen werden.

Denken Sie auch daran, dass OrdinalIgnoreCase eine ganz besondere Art von Bestie ist, bei der ein bisschen Ordnungszahl ausgewählt und ausgewählt wird, verglichen mit einigen lexikografischen Aspekten. Dies kann verwirrend sein.

Sam Safran
quelle
4

Ich denke, es hängt von Ihrer Situation ab. Da bei Ordnungsvergleichen tatsächlich die numerischen Unicode-Werte der Zeichen berücksichtigt werden, sind sie nicht die beste Wahl, wenn Sie alphabetisch sortieren. Für Zeichenfolgenvergleiche wäre die Ordnungszahl jedoch etwas schneller.

Bullines
quelle
1

Es hängt davon ab, was Sie wollen, obwohl ich mich vor invarianter Kultur scheuen würde, es sei denn, Sie sind sich sehr sicher, dass Sie den Code für andere Sprachen niemals lokalisieren möchten. Verwenden Sie stattdessen CurrentCulture.

Außerdem sollte OrdinalIgnoreCase Zahlen berücksichtigen, die möglicherweise Ihren Wünschen entsprechen oder nicht.

Joel Coehoorn
quelle
1
Haben Sie jemals VB6-Code in einer Umgebung mit gemischten Sprachen geschrieben? Sie können Code erstellen, der auf einem PC mit dem französischen Gebietsschema kompiliert wird, auf PCs mit dem englischen Gebietsschema jedoch nicht kompiliert wird, da alle in den Formularressourcen gespeicherten Zahlen das Format des aktuellen Gebietsschemas verwenden. Ich würde argumentieren, dass Sie den umgekehrten Ansatz wählen müssen: Seien Sie sehr vorsichtig, wenn Sie die aktuelle Kultur verwenden. Denken Sie immer daran, ob Ihr System noch funktioniert, wenn sich seine Daten zwischen den Kulturen bewegen. Gleiches gilt für Zeitzonen.
Wim Coenen
Ich stimme der Antwort "es kommt darauf an" zu. obwohl nicht dem "Respekt Zahlen" Bit folgen?
Sam Saffron
-1

Die sehr einfache Antwort lautet: Wenn Sie kein Türkisch verwenden, müssen Sie InvariantCulture nicht verwenden.

Siehe folgenden Link:

Was ist in C # der Unterschied zwischen ToUpper () und ToUpperInvariant ()?

TheMoot
quelle
5
Diese Antwort mag einfach sein, ist aber auch sehr falsch. Das türkische "Ich" ist nur ein Beispiel , es gibt viele weitere mögliche Fallstricke.
Ohad Schneider
Welche weiteren Fallstricke? Ich kenne nur den türkischen Problemfall.
HelloWorld
Ja, neben Türkisch gibt es auch Aserbaidschanisch. Aber das ist es.
Jim Balter