Turkish casing, and why "file".ToUpper() can return FİLE
Turkish has two i letters. Dotless ı uppercases to I, and dotted i uppercases to İ. A culture-aware uppercase under tr-TR therefore turns "file" into "FİLE" and "KITAP_ID" into "kitap_ıd" on the way back down. That is correct for Turkish prose and wrong for everything else.
It becomes a bug the moment an identifier passes through it: a column name, a file extension, an HTTP header, a culture code. In .NET, ToUpper() and ToLower() use the current culture by default, so the same code produces different results depending on the machine it runs on — which is why the failure usually appears in production and not on the developer laptop.
This converter shows both results side by side. Anything that is an identifier wants invariant casing; only text shown to a human wants the Turkish rules.
What should I use in C#?
- ToUpperInvariant() and ToLowerInvariant() for identifiers, and string.Equals(a, b, StringComparison.OrdinalIgnoreCase) for comparisons. Reach for the culture-aware overloads only when the result is displayed to a person.
Does JavaScript have the same problem?
- Not by default: toUpperCase() is locale-independent, so it never produces İ. Only toLocaleUpperCase('tr') does — which means the bug is opt-in in the browser and opt-out in .NET.