Mam taki kod:
If key.Equals("search", StringComparison.OrdinalIgnoreCase) Then
DoSomething()
End If
Nie obchodzi mnie sprawa. Powinno się używać OrdinalIgnoreCase
, InvariantCultureIgnoreCase
lub CurrentCultureIgnoreCase
?
Mam taki kod:
If key.Equals("search", StringComparison.OrdinalIgnoreCase) Then
DoSomething()
End If
Nie obchodzi mnie sprawa. Powinno się używać OrdinalIgnoreCase
, InvariantCultureIgnoreCase
lub CurrentCultureIgnoreCase
?
Odpowiedzi:
Z „ nowych zaleceń dotyczących używania ciągów znaków w Microsoft .NET 2.0 ” MSDN
Podsumowanie: Właściciele kodu, którzy poprzednio używali
InvariantCulture
do porównywania ciągów, wielkości liter i sortowania, powinni zdecydowanie rozważyć użycie nowego zestawuString
przeciążeń w Microsoft .NET 2.0. W szczególności, dane, które są zaprojektowane, aby być kulturowo i językowo nieistotny agnostykiem powinny rozpocząć podając przeciążeń przy użyciu alboStringComparison.Ordinal
czyStringComparison.OrdinalIgnoreCase
członkowie nowegoStringComparison
wyliczenia. Wymuszają one porównywanie bajt po bajcie, podobne dostrcmp
tego, które nie tylko zapobiega błędom wynikającym z językowej interpretacji zasadniczo symbolicznych ciągów, ale zapewnia lepszą wydajność.
"Straße"
i "STRASSE"
. Podczas korzystania z OrdinalIgnoreCase
tych Equals
zwrotów false
, podczas gdy InvariantCultureIgnoreCase
mówi, że są równe.
Porównanie ciągów znaków Unicode jest trudne:
Implementacja wyszukiwania ciągów znaków Unicode i porównań w oprogramowaniu do przetwarzania tekstu musi uwzględniać obecność równoważnych punktów kodowych. W przypadku braku tej funkcji użytkownicy szukający określonej sekwencji punktów kodowych nie byliby w stanie znaleźć innych wizualnie nierozróżnialnych glifów, które mają inną, ale kanonicznie równoważną reprezentację punktu kodowego.
patrz: http://en.wikipedia.org/wiki/Unicode_equivalence
Jeśli próbujesz porównać 2 ciągi znaków Unicode w sposób niewrażliwy na wielkość liter i chcesz, aby działały WSZĘDZIE , masz niemożliwy do rozwiązania problem.
Klasycznym przykładem jest tureckie i , które, gdy jest duże, zmienia się w İ (zwróć uwagę na kropkę)
Domyślnie .Net framework zwykle używa CurrentCulture do funkcji związanych z ciągami, z bardzo ważnym wyjątkiem, .Equals
że używa porównania porządkowego (bajt po bajcie).
Z założenia prowadzi to do tego, że różne funkcje łańcuchowe zachowują się różnie w zależności od kultury komputera.
Niemniej jednak czasami potrzebujemy porównania „ogólnego przeznaczenia”, bez uwzględniania wielkości liter.
Na przykład możesz chcieć, aby porównanie ciągów zachowywało się w ten sam sposób, niezależnie od komputera, na którym jest zainstalowana Twoja aplikacja.
Aby to osiągnąć, mamy 3 opcje:
Reguły równoważności Unicode są skomplikowane, co oznacza, że użycie metody 1) lub 2) jest droższe niż OrdinalIgnoreCase
. Fakt, że OrdinalIgnoreCase
nie wykonuje żadnej specjalnej normalizacji Unicode, oznacza, że niektóre ciągi, które renderują się w ten sam sposób na ekranie komputera, nie będą uważane za identyczne. Na przykład: "\u0061\u030a"
i "\u00e5"
oba renderują å. Jednak w porównaniu porządkowym zostanie uznany za inny.
To, który wybierzesz, zależy w dużej mierze od budowanej aplikacji.
Firma Microsoft ma swój zestaw zaleceń z wyraźnymi wskazówkami. Jednak naprawdę ważne jest, aby zrozumieć pojęcie równoważności Unicode przed przystąpieniem do tych problemów.
Należy również pamiętać, że OrdinalIgnoreCase to bardzo szczególny rodzaj bestii, czyli wybieranie i wybieranie odrobiny porównania porządkowego z kilkoma mieszanymi aspektami leksykograficznymi. To może być mylące.
To zależy od tego, co chcesz, ale ja unikają InvariantCulture chyba że jesteś bardzo pewny, że nigdy nie będziesz chciał zlokalizować kod dla innych języków. Zamiast tego użyj CurrentCulture.
Ponadto OrdinalIgnoreCase powinien respektować liczby, które mogą, ale nie muszą, być tym, czego chcesz.
Bardzo prosta odpowiedź brzmi: jeśli nie używasz języka tureckiego, nie musisz używać InvariantCulture.
Zobacz poniższy link:
Jaka jest różnica między ToUpper () a ToUpperInvariant () w języku C #?