つい忘れてしまうのでメモっておきます。
.NET Framework の String.CompareTo(String) は Char.CompareTo(Char) と異なる基準で文字を比較します。List<String> と List<Char> に ASCII 文字をつっこんで List<T>.Sort() すると一目瞭然です。List<T>.Sort() はデフォルトで CompareTo 使うため、これで違いを確認できます。
using System;
using System.Collections.Generic;
...
Listc_list = new List ();
Lists_list = new List ();
for (int i = 0; ' ' + i <= '~'; i++) {
char c = (char)(' ' + i);
c_list.Add(c);
s_list.Add(new string(c, 1));
}
c_list.Sort();
foreach (char c in c_list) {
Console.Write(c);
}
Console.WriteLine();
s_list.Sort();
foreach (string s in s_list) {
Console.Write(s);
}
Console.WriteLine();
結果は以下です。
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
'- !"#$%&()*,./:;?@[]^_`{|}~+<=>\0123456789aAbBcCdDeEfFgGhHiIjJkKlLmMnNoOpPqQrRsStTuUvVwWxXyYzZ
List<Char> のほうは ASCII コード順にソートされていますが、List<String> のほうはなにやら愉快なことになっています。
String.CompareOrdinal() という Char.CompareTo(Char) と同じ基準で比較をするスタティックメソッドがあるので、これを delegate にして渡してやると同じ結果になります。
s_list.Sort(delegate(string a, string b) { return string.CompareOrdinal(a, b); });
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~
!"#$%&'()*+,-./0123456789:;<=>?@ABCDEFGHIJKLMNOPQRSTUVWXYZ[\]^_`abcdefghijklmnopqrstuvwxyz{|}~