多个对象经常需要排序,来满足项目需求。今天简单写个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 }
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 }
2 {
3 Male = 0,
4 Female = 1
5 }
有了学生类,开始创建泛型的集合:
学生集合的代码
1 //创建泛型集合
2 List<Student> students = new List<Student>();
3 students.Add(new Student ("EEE", 0, GenderEnumer.Male));
4 students.Add(new Student ("DDD", 1, GenderEnumer.Female));
5 students.Add(new Student ("CCC", 2, GenderEnumer.Male));
6 students.Add(new Student ("BBB", 3, GenderEnumer.Female));
7 students.Add(new Student ("AAA", 4, GenderEnumer.Male));
2 List<Student> students = new List<Student>();
3 students.Add(new Student ("EEE", 0, GenderEnumer.Male));
4 students.Add(new Student ("DDD", 1, GenderEnumer.Female));
5 students.Add(new Student ("CCC", 2, GenderEnumer.Male));
6 students.Add(new Student ("BBB", 3, GenderEnumer.Female));
7 students.Add(new Student ("AAA", 4, GenderEnumer.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 };
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 }
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 }
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 }
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 };
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 }
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 }
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 };
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 };
输出的结果如图:
虽然排序看似不错。但是仅限于单个的排序,如果有属性相同的情况,比如性别这个属性,如图:
所以可能还需要进行二级的排序,甚至多级排序,先写到这,以后再改进。
源码备份地址
--小小的天,有大大的梦想!