为了像Windows一样,对于 字符串保证排序不会乱,可以自定义排序方法。
这里采用CompareStringEx来实现。
第一步,声明CompareStringEx
static readonly Int32 NORM_IGNORECASE = 0x00000001; static readonly Int32 NORM_IGNORENONSPACE = 0x00000002; static readonly Int32 NORM_IGNORESYMBOLS = 0x00000004; static readonly Int32 LINGUISTIC_IGNORECASE = 0x00000010; static readonly Int32 LINGUISTIC_IGNOREDIACRITIC = 0x00000020; static readonly Int32 NORM_IGNOREKANATYPE = 0x00010000; static readonly Int32 NORM_IGNOREWIDTH = 0x00020000; static readonly Int32 NORM_LINGUISTIC_CASING = 0x08000000; static readonly Int32 SORT_STRINGSORT = 0x00001000; static readonly Int32 SORT_DIGITSASNUMBERS = 0x00000008; static readonly String LOCALE_NAME_USER_DEFAULT = null; static readonly String LOCALE_NAME_INVARIANT = String.Empty; static readonly String LOCALE_NAME_SYSTEM_DEFAULT = "!sys-default-locale"; [DllImport("kernel32.dll", CharSet = CharSet.Unicode)] static extern Int32 CompareStringEx( String localeName, Int32 flags, String str1, Int32 count1, String str2, Int32 count2, IntPtr versionInformation, IntPtr reserved, Int32 param );
第二步,实现IComparer接口:
class LexicographicalComparer : IComparer<String> { readonly String locale; public LexicographicalComparer() : this(CultureInfo.CurrentCulture) { } public LexicographicalComparer(CultureInfo cultureInfo) { if (cultureInfo.IsNeutralCulture) this.locale = LOCALE_NAME_INVARIANT; else this.locale = cultureInfo.Name; } public Int32 Compare(String x, String y) { // CompareStringEx return 1, 2, or 3. Subtract 2 to get the return value. return CompareStringEx( this.locale, SORT_DIGITSASNUMBERS, // Add other flags if required. x, x.Length, y, y.Length, IntPtr.Zero, IntPtr.Zero, 0) - 2; } }
第三步,调用如下:
var names = new [] { "2.log", "10.log", "1.log" }; var sortedNames = names.OrderBy(s => s, new LexicographicalComparer());