2015-01-15 18 views
5

Dlaczego pod .net (Windows 8) to porównanie łańcuchów zwraca true?Dlaczego ciąg " u0022" zaczyna się od tego ciągu " u204D"

"\u0022".StartsWith("\u204D"); 

Jest to prawdą w przypadku wszystkich kultur i jeśli zmienisz wartość StartsWith na równą, zwróci ona wartość false.

Istnieje wiele różnych znaków, które zwracają wartość true dla porównania StartSWith. Czy jest to część nieparzystej reguły Unicode, czy też Windows ma tu swoje własne reguły?

+0

Spójrz nazwę prawym char w Unicode stół. Porównywania Unicode są subtelne. Na przykład pewne znaki (na przykład zero-szerokość (nie) stolarskie lub niektóre modyfikatory) są ignorowane w porównaniach kopuł. – CodesInChaos

+0

Jeśli potrzebujesz prostych reguł, użyj porównań porządkowych. – CodesInChaos

+0

@CodesInChaos Chcesz przejść do wersji zwykłej i przechodzę przez możliwe zmiany, kiedy pojawił się ten i wiele innych. – Zoom

Odpowiedz

0

Nie jest łatwo wiedzieć, jakie zasady leżą w zależnych od kultury porównaniach łańcuchów. Wydaje się całkiem spójne, że znaki interpunkcyjne U + 0022 " (ZNAK CYTATYCZNY) i U + 204D (CZARNY PULPITY DO RIGHTWARDS) są uważane za "wystarczająco równe" w porównaniach kultur (w tym z kulturami niezmiennymi). Wszystkie te przykłady wskazują, że:

// culture-sensitive: 

Console.WriteLine("\"".StartsWith("⁍")); 
Console.WriteLine("⁍".StartsWith("\"")); 
Console.WriteLine("\"".StartsWith("⁍", StringComparison.InvariantCulture)); 
Console.WriteLine("⁍".StartsWith("\"", StringComparison.InvariantCulture)); 

Console.WriteLine("\"".Equals("⁍", StringComparison.CurrentCulture)); 
Console.WriteLine("⁍".Equals("\"", StringComparison.CurrentCulture)); 
Console.WriteLine("\"".Equals("⁍", StringComparison.InvariantCulture)); 
Console.WriteLine("⁍".Equals("\"", StringComparison.InvariantCulture)); 

Console.WriteLine(StringComparer.CurrentCulture.Equals("\"", "⁍")); 
Console.WriteLine(StringComparer.CurrentCulture.Equals("⁍", "\"")); 
Console.WriteLine(StringComparer.InvariantCulture.Equals("\"", "⁍")); 
Console.WriteLine(StringComparer.InvariantCulture.Equals("⁍", "\"")); 

Console.WriteLine("\"".CompareTo("⁍")); 
Console.WriteLine("⁍".CompareTo("\"")); 

Console.WriteLine(StringComparer.CurrentCulture.Compare("\"", "⁍")); 
Console.WriteLine(StringComparer.CurrentCulture.Compare("⁍", "\"")); 
Console.WriteLine(StringComparer.InvariantCulture.Compare("\"", "⁍")); 
Console.WriteLine(StringComparer.InvariantCulture.Compare("⁍", "\"")); 

Inne przykłady mogły być podane, na przykład metody static na string, ale są one równoważne.

Z porządkowej porównania, na pewno U + 0022 muszą być różne od (mniej niż) U + 204D (to jest proste!):

// ordinal: 

Console.WriteLine("\"".StartsWith("⁍", StringComparison.Ordinal)); 
Console.WriteLine("⁍".StartsWith("\"", StringComparison.Ordinal)); 

Console.WriteLine("\"".Equals("⁍")); 
Console.WriteLine("⁍".Equals("\"")); 

Console.WriteLine(StringComparer.Ordinal.Equals("\"", "⁍")); 
Console.WriteLine(StringComparer.Ordinal.Equals("⁍", "\"")); 

Console.WriteLine(StringComparer.Ordinal.Compare("\"", "⁍")); 
Console.WriteLine(StringComparer.Ordinal.Compare("⁍", "\""));