Porównywanie ciągów w C # jest dość proste. W rzeczywistości istnieje kilka sposobów, aby to zrobić. Niektóre wymieniłem w poniższym bloku. Zastanawiam się, jakie są między nimi różnice i kiedy należy używać jednego nad innymi? Czy należy tego unikać za wszelką cenę? Czy jest jeszcze coś, czego nie wymieniłem?
string testString = "Test";
string anotherString = "Another";
if (testString.CompareTo(anotherString) == 0) {}
if (testString.Equals(anotherString)) {}
if (testString == anotherString) {}
(Uwaga: szukam równości w tym przykładzie, nie mniej niż lub więcej niż, ale mogę również komentować)
c#
string
comparison
Craig
źródło
źródło
Odpowiedzi:
Oto zasady działania tych funkcji:
stringValue.CompareTo(otherStringValue)
null
jest przed sznurkiemCultureInfo.CurrentCulture.CompareInfo.Compare
, co oznacza, że użyje porównania zależnego od kultury. Może to oznaczać, żeß
będzie to równeSS
w Niemczech lub podobniestringValue.Equals(otherStringValue)
null
nie jest uważany za coś równegoStringComparison
opcję, użyje czegoś, co wygląda jak bezpośrednia kontrola równości porządkowej, tj.ß
nie jest tym samym, coSS
w dowolnym języku lub kulturzestringValue == otherStringValue
stringValue.Equals()
.==
Operator wywołuje statycznąEquals(string a, string b)
metodę (który z kolei przechodzi do wewnętrznegoEqualsHelper
zrobić porównanie..Equals()
nanull
ciąg dostajenull
wyjątek odniesienia, podczas gdy na==
nie.Object.ReferenceEquals(stringValue, otherStringValue)
Po prostu sprawdza, czy referencje są takie same, tzn. Nie są to tylko dwa ciągi o tej samej treści, porównujesz sam obiekt łańcuchowy.
Zauważ, że przy powyższych opcjach, które używają wywołań metod, występują przeciążenia z większą liczbą opcji określających sposób porównywania.
Moja rada, jeśli chcesz po prostu sprawdzić równość, zdecyduj, czy chcesz użyć porównania zależnego od kultury, czy nie, a następnie użyj
.CompareTo
lub.Equals
, w zależności od wyboru.źródło
String.Compare
?Z MSDN:
Sugerują używanie
.Equals
zamiast.CompareTo
szukania wyłącznie równości. Nie jestem pewien, czy istnieje różnica pomiędzy.Equals
i==
postring
zajęciach. Czasami będę używać.Equals
lubObject.ReferenceEquals
zamiast==
moich własnych klas, na wypadek gdyby ktoś pojawił się później i przedefiniował==
operatora tej klasy.źródło
Jeśli kiedykolwiek jesteś ciekawy różnic w metodach BCL, Reflector jest twoim przyjacielem :-)
Przestrzegam tych wytycznych:
Dopasowanie ścisłe: EDYCJA: Wcześniej zawsze używałem operatora == na zasadzie, że wewnątrz Equals (ciąg, ciąg) operator obiektu == służy do porównywania odniesień do obiektu, ale wydaje się, że strA.Equals (strB) wciąż wynosi 1-11% ogólnie szybciej niż string.Equals (strA, strB), strA == strB i string.CompareOrdinal (strA, strB). Testowałem w pętli za pomocą StopWatch zarówno dla wewnętrznych, jak i nie internowanych wartości łańcuchów, z tymi samymi / różnymi długościami łańcuchów i różnymi rozmiarami (1B do 5 MB).
Dopasowanie czytelne dla człowieka (kultury zachodnie, bez rozróżniania wielkości liter):
Dopasowanie czytelne dla człowieka (Wszystkie inne kultury, niewrażliwa wielkość liter / akcent / kana / itd. Zdefiniowane przez CultureInfo):
Dopasowanie czytelne dla człowieka z niestandardowymi regułami (Wszystkie inne kultury):
źródło
Jak powiedział Ed , do sortowania używa się CompareTo.
Istnieje jednak różnica między .Equals a ==.
== rozwiązuje zasadniczo następujący kod:
Prostym powodem jest wyjątek:
A następujące nie będą:
źródło
Dobre objaśnienia i praktyki dotyczące problemów z porównywaniem ciągów można znaleźć w artykule Nowe zalecenia dotyczące używania ciągów w Microsoft .NET 2.0, a także w najlepszych praktykach dotyczących używania ciągów w .NET Framework .
Każda z wymienionych metod (i innych) ma określony cel. Kluczowa różnica między nimi polega na tym, jakiego rodzaju wyliczenia StringComparison używają domyślnie. Istnieje kilka opcji:
Każdy z powyższych typów porównania dotyczy innego przypadku użycia:
Uwaga: Wyliczenie StringComparison, a także przeciążenia metod porównywania ciągów, istnieją od wersji .NET 2.0.
String.CompareTo Method (String)
Jest w rzeczywistości bezpieczną implementacją metody IComparable.CompareTo . Domyślna interpretacja: CurrentCulture.
Stosowanie:
A zatem
Metoda String.Compare
Statyczny element klasy String, który ma wiele przeciążeń. Domyślna interpretacja: CurrentCulture.
Metoda String.Equals
Przesłonięty z klasy Object i przeciążony dla bezpieczeństwa typu. Domyślna interpretacja: porządkowa. Zauważ, że:
Klasa StringComparer
Istnieje również inny sposób radzenia sobie z porównaniami ciągów, w szczególności w celu sortowania:
źródło
Nie chodzi o to, że wydajność zwykle ma znaczenie w 99% przypadków, gdy musisz to zrobić, ale jeśli musiałbyś to zrobić kilka milionów razy w pętli, wysoce sugerowałbym, abyś użył .Equals lub ==, ponieważ jak tylko znajdzie postać to nie pasuje, wyrzuca to wszystko jako fałszywe, ale jeśli użyjesz CompareTo, będzie musiał dowiedzieć się, która postać jest mniejsza od drugiej, co prowadzi do nieco gorszego czasu wydajności.
Jeśli Twoja aplikacja będzie działać w różnych krajach, radzę przyjrzeć się implikacjom CultureInfo i ewentualnie użyć .Equals. Ponieważ tak naprawdę piszę aplikacje tylko dla USA (i nie obchodzi mnie, czy ktoś nie działa poprawnie), zawsze używam ==.
źródło
W wymienionych tutaj formularzach nie ma między nimi dużej różnicy.
CompareTo
kończy się wywołaniemCompareInfo
metody, która dokonuje porównania przy użyciu bieżącej kultury;Equals
jest wywoływany przez==
operatora.Jeśli weźmiesz pod uwagę przeciążenia, wtedy sprawy będą się różnić.
Compare
i==
może użyć bieżącej kultury tylko do porównania łańcucha.Equals
iString.Compare
może przyjąćStringComparison
argument wyliczenia, który pozwala określić porównanie bez rozróżniania kultur lub bez rozróżniania wielkości liter. TylkoString.Compare
pozwala na podanieCultureInfo
i przeprowadzenia porównań przy użyciu kulturę, inny niż domyślny kultury.Ze względu na jego wszechstronność używam
String.Compare
więcej niż jakiejkolwiek innej metody porównania; pozwala mi dokładnie określić, czego chcę.źródło
Jedną z DUŻYCH różnic, na które należy zwrócić uwagę, jest to, że .Equals () wyrzuci wyjątek, jeśli pierwszy ciąg jest pusty, podczas gdy == nie.
źródło
źródło
Korzystanie z .Equals jest również znacznie łatwiejsze do odczytania .
źródło
z .Equals zyskujesz także opcje StringComparison. bardzo przydatny do ignorowania sprawy i innych rzeczy.
btw, to da wynik fałszywy
Ponieważ == porównuje wartości aib (które są wskaźnikami), będzie to miało wartość prawdy tylko wtedy, gdy wskaźniki wskażą ten sam obiekt w pamięci. .Equals dereferentuje wskaźniki i porównuje wartości zapisane w wskaźnikach. a. Równości (b) byłyby tutaj prawdziwe.
a jeśli zmienisz b na:
wtedy a. Równania (b) są fałszywe, ale
byłoby prawdą
a.CompareTo (b) wywołuje funkcję CompareTo ciągu, która porównuje wartości wskaźników i zwraca <0, jeśli wartość przechowywana w a jest mniejsza niż wartość przechowywana w b, zwraca 0, jeśli a. Equals (b) jest prawdą, i > 0 w przeciwnym razie. Jednak w tym rozróżniana jest wielkość liter, myślę, że są możliwe opcje, aby CompareTo zignorować wielkość liter i tak dalej, ale nie mam czasu, aby się teraz przyjrzeć. Jak już inni stwierdzili, można to zrobić w celu sortowania. Porównywanie równości w ten sposób spowodowałoby niepotrzebne koszty ogólne.
Jestem pewien, że pomijam pewne rzeczy, ale myślę, że powinno to wystarczyć do rozpoczęcia eksperymentów, jeśli potrzebujesz więcej szczegółów.
źródło