我们完全可以通过调用Windows API 函数来作弊,该函数StrCmpLogicalW()
在两个字符串之间进行自然排序顺序比较。
然后我们可以使用内置的 List.Sort()。根本不需要涉及 Linq:
using System;
using System.Collections.Generic;
using System.Runtime.InteropServices;
namespace Demo
{
class Program
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern int StrCmpLogicalW(string lhs, string rhs);
private void run()
{
var list = new List<KeyValuePair<string, string>>
{
new KeyValuePair<string, string>("1", "Day 1"),
new KeyValuePair<string, string>("2", "Day 11"),
new KeyValuePair<string, string>("4", "Day 5"),
new KeyValuePair<string, string>("6", "Day 13")
};
list.Sort((lhs, rhs) => StrCmpLogicalW(lhs.Value, rhs.Value));
foreach (var keyValuePair in list)
Console.WriteLine(keyValuePair);
}
static void Main(string[] args)
{
new Program().run();
}
}
}
我假设您确实想按“值”而不是“键”排序,并且您遇到的问题是字符串编号没有按数字顺序排序。
编辑:应用 Jim Tollan 的想法,您可以创建一个扩展方法来隐藏 PInvoke,如下所示:
public static class ListExt
{
[DllImport("shlwapi.dll", CharSet = CharSet.Unicode)]
private static extern int StrCmpLogicalW(string lhs, string rhs);
// Version for lists of any type.
public static void SortNatural<T>(this List<T> self, Func<T, string> stringSelector)
{
self.Sort((lhs, rhs) => StrCmpLogicalW(stringSelector(lhs), stringSelector(rhs)));
}
// Simpler version for List<string>
public static void SortNatural(this List<string> self)
{
self.Sort(StrCmpLogicalW);
}
}
然后对列表进行排序的行将如下所示:
list.SortNatural(element => element.Value);