使用CompareStringEx来重新排序
为了像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{ 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());