最稳妥复用排序逻辑应实现 icomparer 接口;临时简单排序用 orderby() 或 sort(comparison);sort() 不接受 icomparer 的 lambda,因 comparison 是委托而 icomparer 是有状态的类型;comparer.create() 可快速生成 icomparer 实例。

直接用 List<t>.Sort()</t> 配合自定义 IComparer<t></t> 是最稳妥、可复用性最强的方式,尤其适合多处需要相同排序逻辑的场景;临时简单排序优先用 OrderBy()(LINQ),但注意它返回新列表,不改变原集合。
为什么不能直接传 lambda 给 Sort()?
List<t>.Sort()</t> 本身重载很多,但接受 lambda 的只有 Comparison<t></t> 版本,不是 IComparer<t></t> —— 这俩接口语义不同:Comparison<t></t> 是函数委托((a,b) => int),而 IComparer<t></t> 是类型实例,支持状态和复用。
常见错误现象:list.Sort((x, y) => x.Age.CompareTo(y.Age)); 能编译运行,但它走的是 Comparison<t></t> 重载,不是 IComparer<t></t>。如果你真要实现 IComparer<t></t>,就不能传 lambda,得传一个实现了该接口的类或实例。
- 想复用排序逻辑(比如多个 List 都按“姓名长度升序+年龄降序”排)→ 必须实现
IComparer<t></t> - 只排一次、逻辑简单 → 直接用
Comparison<t></t>lambda 更轻量 - 需要在比较中访问外部变量(如当前用户偏好)→
IComparer<t></t>实现类里可持字段,比闭包更可控
写一个可复用的 IComparer 实现类
关键点:必须实现 int Compare(T x, T y) 方法,返回负数(x 在 y 前)、0(相等)、正数(x 在 y 后)。不要在方法里抛异常,也不建议做 null 检查以外的业务校验——排序过程可能高频调用,性能敏感。
public class PersonComparer : IComparer<person>
{
public int Compare(Person? x, Person? y)
{
if (x == null && y == null) return 0;
if (x == null) return -1;
if (y == null) return 1;
var nameCmp = string.Compare(x.Name, y.Name, StringComparison.Ordinal);
if (nameCmp != 0) return nameCmp;
return y.Age.CompareTo(x.Age); // 年龄降序
}
}</person>
使用:people.Sort(new PersonComparer());
- 类名建议带
Comparer后缀,符合 .NET 命名习惯 - 泛型参数必须和
List<t></t>的T严格一致,否则编译不通过 - 如果
Compare方法里用了string.Compare,记得传StringComparison明确指定比较方式,避免文化相关行为
用 Comparer.Create() 快速创建 IComparer 实例
这是 .NET 4.5+ 提供的捷径,免去写完整类,又比 lambda 更贴近 IComparer<t></t> 语义——它内部封装了 Comparison<t></t>,但返回的是 IComparer<t></t> 实例,能传给所有只认 IComparer<t></t> 的 API(比如 SortedSet<t></t> 构造函数)。
示例:var comparer = Comparer<person>.Create((x, y) => x.Name.Length.CompareTo(y.Name.Length));</person>
- 适用于逻辑不复杂、但必须传
IComparer<t></t>的场景(比如第三方库要求) - 注意:每次调用
Create()都新建实例,别在循环里反复调用 - 不能捕获局部变量并修改(比如
var order = "asc"; ... Create((x,y) => order=="asc" ? ...)),因为order是闭包变量,值固定在创建时
真正容易被忽略的是:当你的 Compare 方法返回值不是严格 -1/0/1,而是任意负/零/正整数时,没问题;但若逻辑出错(比如漏了 return 或写了 return bool),运行时可能抛 ArgumentException: At least one object must implement IComparable,实际是 Compare 返回了非 int 类型或未覆盖所有分支。











