C# List.Sort方法总结

在实现工作中的系统功能时,总是会出现对数据排序的需求,而排序算法在C#中有提前封装好的方法,即List.Sort

1. Sort方法的四种重载

在List中可以看到,分别为

csharp 复制代码
List<T>.Sort();   
List<T>.Sort(IComparer<T> Comparer);
List<T>.Sort(int index, int count, IComparer<T> Comparer);
List<T>.Sort(Comparison<T> comparison);

其中,第一,第二两个方法内部其实都是在调用第三个方法,只不过参数传的不一样。

第三个方法的index参数表示从哪个索引开始,count表示要排序的个数,comparer表示实现了IComparer接口的类型,用于实现排序规则,可以看到前两个方法都是从头开始全量排序。

最终调用的都是Array.Sort()方法

2. 具体使用

- List.Sort();




可以看到对于int类型默认是实现升序排序的,对于bool类型,false会排在true前面

那如果是一个复杂类型呢?


可以看到,传的是一个Demo类型的对象,但是直接使用Sort方法会报错,提示"未能比较数组中的两个元素,必须至少有一个对象实现IComparable"

那么为什么会报这个错呢,深入源码来看,从调用堆栈看应该是走到了这一步,在Array中

继续深入,来到ArraySortHelper类

注意此时的comparer因为是null,所以给了一个Comparer.Default

最终来到了

然后在调用comparer.Compare方法时报错

深入Comparer类,查看Default

即最终调用的是ObjectComparer.Compare方法

进行最终深入,来到Comparer类的Compare方法

首先会判断m_compareInfo是否为空,那么看上面

可以看到,虽然Default会传入一个compareInfo,但是因为传入的对象类型在强制类型转换为string后其实是null,所以会进行下面的判断。

即比较的最终执行是判断比较的两个对象是否实现了IComparable接口,而传入的Demo类型并没有实现这个接口,所以最终报错

- IComparable 接口

按照上面探索的结果,直接使用Sort方法最终会判断传入类型是否实现了IComparable 接口,那么int类型和bool类型能够直接使用说明两者实现了IComparable 接口

先看int类型

可以看到int实现了IComparable 的CompareTo方法,规则为小于返回-1,大于返回1,等于返回0,说明此时返回-1是升序,返回1是降序

再看bool类型

规则为等于返回0,如果自身为false返回-1,如果自身为true,返回1

再回到

可以看到,当comparer.Compare返回大于0时,会将比较的双方进行交换,所以int类型和bool类型的最终结果显而易见,即大的数和true会被交换到后面

对于string类型,其也实现了IComparable 接口,但字符串的比较是通过比较每一个字符的Unicode 编码大小,这里不再赘述

- 复杂类型的比较

综上所述,如果需要比较一个复杂的类型,那么必须实现IComparable 接口

比如这里的Demo类型,实现了自定义的比较方法,先比较name,再比较age

或者,使用List.Sort(IComparer Comparer),即需要实现IComparer接口,定义一个比较器

DemoComparer实现了IComparer接口,在内部实现了自定义的Demo类型的比较

- List.Sort(Comparison comparison)

或者

可以看到这里会使用Array的方法,将comparison转换为IComparer的比较器

最终调用的就是传入的Comparison委托

相关推荐
Monly2116 小时前
Java:修改打包配置文件
java·开发语言
我命由我1234516 小时前
Android 广播 - 静态注册与动态注册对广播接收器实例创建的影响
android·java·开发语言·java-ee·android studio·android-studio·android runtime
island131416 小时前
CANN ops-nn 算子库深度解析:核心算子(如激活函数、归一化)的数值精度控制与内存高效实现
开发语言·人工智能·神经网络
xcLeigh16 小时前
Python入门:Python3 requests模块全面学习教程
开发语言·python·学习·模块·python3·requests
xcLeigh16 小时前
Python入门:Python3 statistics模块全面学习教程
开发语言·python·学习·模块·python3·statistics
秋邱17 小时前
用 Python 写出 C++ 的性能?用CANN中PyPTO 算子开发硬核上手指南
开发语言·c++·python
wenzhangli717 小时前
ooderA2UI BridgeCode 深度解析:从设计原理到 Trae Solo Skill 实践
java·开发语言·人工智能·开源
灵感菇_17 小时前
Java 锁机制全面解析
java·开发语言
wazmlp00188736918 小时前
python第三次作业
开发语言·python
娇娇乔木18 小时前
模块十一--接口/抽象方法/多态--尚硅谷Javase笔记总结
java·开发语言