It's because the default StringComparer
is culture-sensitive. As far as I can tell, Comparer<string>.Default
delegates to string.CompareTo(string)
which uses the current culture:
This method performs a word (case-sensitive and culture-sensitive) comparison using the current culture. For more information about word, string, and ordinal sorts, see System.Globalization.CompareOptions
.
Then the page for CompareOptions
includes:
The .NET Framework uses three distinct ways of sorting: word sort, string sort, and ordinal sort. Word sort performs a culture-sensitive comparison of strings. Certain nonalphanumeric characters might have special weights assigned to them. For example, the hyphen ("-") might have a very small weight assigned to it so that "coop" and "co-op" appear next to each other in a sorted list. String sort is similar to word sort, except that there are no special cases. Therefore, all nonalphanumeric symbols come before all alphanumeric characters. Ordinal sort compares strings based on the Unicode values of each element of the string.
("Small weight" isn't quite the same as "ignored" as quoted in Andrei's answer, but the effects are similar here.)
If you specify StringComparer.Ordinal
, you get results of:
66-0616280-00A
66-0616280-10A
66-0616280100A
66-0616280104A
Specify it as the second argument to OrderBy
:
s = s.OrderBy(t => t, StringComparer.Ordinal).ToList();
You can see the difference here:
Console.WriteLine(Comparer<string>.Default.Compare
("66-0616280104A", "66-0616280-10A"));
Console.WriteLine(StringComparer.Ordinal.Compare
("66-0616280104A", "66-0616280-10A"));