惯性聚合 高效追踪和阅读你感兴趣的博客、新闻、科技资讯
阅读原文 在惯性聚合中打开

推荐订阅源

Blog — PlanetScale
Blog — PlanetScale
爱范儿
爱范儿
MongoDB | Blog
MongoDB | Blog
腾讯CDC
aimingoo的专栏
aimingoo的专栏
月光博客
月光博客
Engineering at Meta
Engineering at Meta
C
Check Point Blog
N
Netflix TechBlog - Medium
钛媒体:引领未来商业与生活新知
钛媒体:引领未来商业与生活新知
L
LangChain Blog
大猫的无限游戏
大猫的无限游戏
IT之家
IT之家
Microsoft Security Blog
Microsoft Security Blog
GbyAI
GbyAI
奇客Solidot–传递最新科技情报
奇客Solidot–传递最新科技情报
T
The Blog of Author Tim Ferriss
Last Week in AI
Last Week in AI
B
Blog
让小产品的独立变现更简单 - ezindie.com
让小产品的独立变现更简单 - ezindie.com
人人都是产品经理
人人都是产品经理
博客园 - 叶小钗
WordPress大学
WordPress大学
博客园 - 司徒正美

博客园 - RockyYu

策略模式 unity中的WWW通讯问题 需求分析的方法 用TlbImp.exe生成程序可调用的Dll C++程序引用Dll 查询本地注册表,调用某后缀文件相应的执行程序,并打开文件 windows服务的安装和卸载 FFmpeg和GPL协议 C#POST数据,HttpWebRequest请求页面,HttpWebResponse返回数据 XMLHttpRequest的使用方法 错误: 无法生成临时类 图片滚动效果代码 - RockyYu - 博客园 一个不错的给图片添加说明文字的动态层的代码 - RockyYu - 博客园 截取中文字符串的js方法 js调用XML数据生成DIV 迭代器模式(Iterator Pattern) 创建CLR存储过程 JavaScript Boolean (逻辑)对象 - RockyYu JavaScript文件只在IE6下出错(“未结束的字符串常量”)的解决办法。
List<T>的排序
RockyYu · 2010-07-15 · via 博客园 - RockyYu

多个对象经常需要排序,来满足项目需求。今天简单写个List<T>的排序方法,供日后研究。
先写个学生的类,代码如下:

学生类的代码

 1 /// <summary>
 2 /// 学生类
 3 /// </summary>
 4 public class Student
 5 {
 6     /// <summary>
 7     /// 生成学生对象
 8     /// </summary>
 9     /// <param name="name">姓名</param>
10     /// <param name="age">年龄</param>
11     /// <param name="gender">性别</param>
12     public Student(string name, int age, GenderEnumer gender)
13     {
14         this.name = name;
15         this.age = age;
16         this.gender = gender;
17     }
18     private string name;
19     /// <summary>
20     /// 获取或设置学生的姓名
21     /// </summary>
22     public string Name
23     {
24         get { return this.name; }
25         set { this.name = value; }
26     }
27     private int age;
28     /// <summary>
29     /// 获取或设置学生的年龄
30     /// </summary>
31     public int Age
32     {
33         get { return this.age; }
34         set { this.age = value; }
35     }
36     private GenderEnumer gender;
37     /// <summary>
38     /// 获取或设置学生的性别
39     /// </summary>
40     public GenderEnumer Gender
41     {
42         get { return this.gender; }
43         set { this.gender = value; }
44     }
45 }

这里补上一个性别的枚举类型:

1 public enum GenderEnumer
2 {
3     Male = 0,
4     Female = 1
5 }

有了学生类,开始创建泛型的集合:

学生集合的代码

1 //创建泛型集合
2 List<Student> students = new List<Student>();
3 students.Add(new Student ("EEE"0GenderEnumer.Male));
4 students.Add(new Student ("DDD"1GenderEnumer.Female));
5 students.Add(new Student ("CCC"2GenderEnumer.Male));
6 students.Add(new Student ("BBB"3GenderEnumer.Female));
7 students.Add(new Student ("AAA"4GenderEnumer.Male));

下面我们按照默认的顺序进行输出:

默认顺序输出的代码

1 IEnumerator studentor = students.GetEnumerator();
2 Student student;
3 Console.WriteLine("Default Sort");
4 while (studentor.MoveNext())
5 {
6     student = (Student)studentor.Current;
7     Console.WriteLine("Name:{0}, Age:{1}, Gender:{2}"new object[] { student.Name, student.Age, student.Gender });
8 };

输出如图:

因为要实现List<T>.Sort()所以需要写出IComparer<T>的继承,实现如下:

学生的比较器实现类

 1 /// <summary>
 2 /// 学生的比较器实现类
 3 /// </summary>
 4 public class StudentComparer : IComparer<Student>
 5 {
 6     #region IComparer<Student> 成员
 7 
 8     /// <summary>
 9     /// 泛型比较的实现方法
10     /// </summary>
11     public int Compare(Student x, Student y)
12     {
13         //比较的逻辑,比如return x.Name.CompareTo(y.Name);
14     }
15 
16     #endregion
17 }

添加一个方便以后扩展的枚举,表示进行排序的属性:

1 /// <summary>
2 /// 学生可以比较的属性,也是比较器的类型。
3 /// </summary>
4 public enum StudentComparerType
5 {
6     Name = 0,
7     Age = 1,
8     Gender = 2
9 }

修改一下比较方法的实现:

泛型比较的实现方法(第一次修改)

 1 /// <summary>
 2 /// 泛型比较的实现方法(第一次修改)
 3 /// </summary>
 4 public int Compare(Student x, Student y)
 5 {
 6     switch (Type)
 7     {
 8         case StudentComparerType.Name:
 9             return x.Name.CompareTo(y.Name);
10         case StudentComparerType.Age:
11             return x.Age.CompareTo(y.Age);
12         case StudentComparerType.Gender:
13             return x.Gender.CompareTo(y.Gender);
14         default:
15             return 0;
16     }
17 }

下面按照学生姓名进行排序:

按照姓名排序的输出代码

1 StudentComparer studentCmp = new StudentComparer(StudentComparerType.Name);
2 students.Sort(studentCmp);
3 studentor = students.GetEnumerator();
4 Console.WriteLine("Name Sort");
5 while (studentor.MoveNext())
6 {
7     student = (Student)studentor.Current;
8     Console.WriteLine("Name:{0}, Age:{1}, Gender:{2}"new object[] { student.Name, student.Age, student.Gender });
9 };

 结果输出:

因为也有可能是降序的排序。所以还需要再添加一个排序的方向的枚举:

1 /// <summary>
2 /// 排序的方向,ASC为升序,DESC为降序
3 /// </summary>
4 public enum StudentComparerDirection
5 {
6     ASC = 1,
7     DESC = -1
8 }

再次修改比较的实现方法,如下:

泛型比较的实现方法(第二次修改)

 1 /// <summary>
 2 /// 泛型比较的实现方法(第二次修改)
 3 /// </summary>
 4 public int Compare(Student x, Student y)
 5 {
 6     switch (Type)
 7     {
 8         case StudentComparerType.Name:
 9             return (int)Direction * x.Name.CompareTo(y.Name);
10         case StudentComparerType.Age:
11             return (int)Direction * x.Age.CompareTo(y.Age);
12         case StudentComparerType.Gender:
13             return (int)Direction * x.Gender.CompareTo(y.Gender);
14         default:
15             return 0;
16     }
17 }

添加一个让学生姓名按照降序排列的输出方法:

按照姓名降序排列的代码

 1 studentCmp = new StudentComparer(StudentComparerType.Name);
 2 studentCmp.Direction = StudentComparerDirection.DESC;
 3 students.Sort(studentCmp);
 4 studentor = students.GetEnumerator();
 5 Console.WriteLine("Name DESC Sort");
 6 while (studentor.MoveNext())
 7 {
 8     student = (Student)studentor.Current;
 9     Console.WriteLine("Name:{0}, Age:{1}, Gender:{2}"new object[] { student.Name, student.Age, student.Gender });
10 };

输出的结果如图:

 虽然排序看似不错。但是仅限于单个的排序,如果有属性相同的情况,比如性别这个属性,如图:

所以可能还需要进行二级的排序,甚至多级排序,先写到这,以后再改进。

源码备份地址

/Files/ztlyz/GenericSortTest.rar