Vor einiger Zeit habe ich einen Artikel veröffentlicht, der sich mit ein paar Tipps und Tricks zur Lokalisierung in .NET beschäftigt. Einen wichtigen Hinweis habe ich dabei allerdings nicht berücksichtigt, da er mir zum damaligen Zeitpunkt nicht bewusst war. Es geht um den Unterschied bei der Umwandlung von Zeichenketten in Groß- beziehungsweise Kleinbuchstaben.
Das hört sich im ersten Moment vielleicht merkwürdig an. Was muss bei der Umwandlung von Zeichenketten in Groß- beziehungsweise Kleinbuchstaben schon berücksichtigt werden? Einfach brav und je nach Einsatzzweck ToUpper
oder ToLower
auf der Zeichenkette aufrufen und glücklich sein. Für die meisten Kulturen stimmt das auch. Bei anderen Kulturen wiederum ist das nicht so einfach.
Folgender Gist enthält einen minimalen und simplen Unit-Test, der das Problem verdeutlichen soll.
[gist id=4953060 file=LocalizationTests.cs]
Die Assert
-Anweisung ist schon ein Hinweis darauf, ob der Vergleich übereinstimmt oder nicht. Er stimmt nicht überein. Die Methode AreNotEqual
wurde benutzt, damit der Unit-Test als bestanden markiert wird. Dieses Ergebnis finde ich verwunderlich. Egal wie und wie oft die beiden Zeichenketten lowerCharacters
und upperCharacters
umgewandelt werden, das Ergebnis sollte identisch sein. Die türkische Kultureinstellung sorgt aber ganz offensichtlich dafür, dass ein Kleinbuchstabe, der in einen Großbuchstaben umgewandelt wird, nicht identisch zu den Großbuchstaben ist, die im Code direkt als Zeichenkette hinterlegt sind.
Der Grund dafür wird deutlich, wenn der Debug-Modus bemüht wird. Werden die Großbuchstaben in Kleinbuchstaben umgewandelt, ist das Ergebnis die Zeichenkette abcdefghıjklmnopqrstuvwxyz
. Bei der Umwandlung von Kleinbuchstaben in Großbuchstaben kommt als Ergebnis ABCDEFGHİJKLMNOPQRSTUVWXYZ
zustande. In beiden Fällen habe ich den Buchstaben, der für den negativen Vergleich verantwortlich ist, rot markiert. Es sind das kleine i
sowie das große I
.
Das ist solange kein Problem, wie diese Zeichen auch im Code verwendet werden. Das ist in der Regel aber nicht der Fall, möchte ich behaupten. Problematisch ist das Verhalten auch aus dem Grund, dass nach der Umwandlung keine Möglichkeit mehr besteht, einen positiven Vergleich durchzuführen, wenn in der Zeichenkette für den Vergleich nicht die speziellen Zeichen vorkommen. Selbst ein Aufruf von String.Compare
mit der türkischen Kultur und der Option CompareOptions.IgnoreCase
funktioniert nicht. Die Zeichen sind nach der Umwandlung unterschiedlich, was in einem Vergleich nicht mehr einfach ignoriert werden kann.
Abschließend stand noch die Frage im Raum, ob es möglicherweise noch andere Kulturen gibt, die ein ähnliches Verhalten zeigen. Das folgende Gist zeigt eine kleine Konsolenanwendung, die diese Frage beantwortet.
[gist id=4953341 file=Program.cs]
Überprüft wird, ob es einen Unterschied in den umgewandelten Zeichen gibt. Tritt so ein Fall ein, wird die gerade verwendete Kultur ausgegeben. Das Resultat dieser minimalen Anwendung ist eine Liste von sieben Kulturen.
- tr
- az
- tr-TR
- az-Latn-AZ
- az-Cyrl-AZ
- az-Cyrl
- az-Latn
Die Anwendung überprüft alle Kulturen, die auf meinem Rechner installiert sind, was zurzeit 378 Kulturen entspricht. Beim Vergleich von umgewandelten Zeichenketten dieser Kultureinstellungen sollte also einmal mehr hingesehen werden.
Schreibe einen Kommentar