原文地址:https://www.cnblogs.com/pizzabig/p/5341088.html
仅仅为了自己查看方便。
在c#中自定义类型实现比较和排序需要自定义类实现IComparable接口,需要实现一个名为CompareTo的方法,返回值为int唯一参数为object。
1.创建一个员工类包含Id Name Salary三个属性 继承自IComparable接口并实现CompareTo方法
1 using System;
2 using System.Collections;
3 using System.Collections.Generic;
4 using System.Linq;
5 using System.Text;
6 using System.Threading.Tasks;
7
8 namespace IComparableTest2 {
9 class Program {
10 static void Main(string[] args) {
11 var myList = new ArrayList();
12 myList.Add(new Employee(002, "Sam", 3000));
13 myList.Add(new Employee(001, "Mary", 2800));
14 myList.Add(new Employee(003, "Jick", 3800));
15 myList.Add(new Employee(004, "July", 3200));
16 myList.Sort();
17 foreach (var e in myList)
18 {
19 Console.WriteLine(e.ToString());
20 }
21 Console.ReadKey();
22 }
23 }
24
25 class Employee : IComparable {
26 public int Id { get; set; }
27 public string Name { get; set; }
28 public int Salary { get; set; }
29
30 public Employee(int id, string name, int salary) {
31 this.Id = id;
32 this.Name = name;
33 this.Salary = salary;
34 }
35
36 public override string ToString() {
37 return "ID:" + Id + " Name:" + Name + " Salary:" + Salary;
38 }
39
40 public int CompareTo(object o) {
41 Employee others = (Employee)o;
42 if (this.Id > others.Id)
43 {
44 return 1;
45 }
46 else if (this.Id < others.Id)
47 {
48 return -1;
49 }
50 else
51 {
52 return 0;
53 }
54 }
55 }
56 }
上面的CompareTo方法对Id作比较,Employee将会以Id作为键做比较,排序时键值为Id做升序。
输出结果:
ID:1 Name:Mary Salary:2800
ID:2 Name:Sam Salary:3000
ID:3 Name:Jick Salary:3800
ID:4 Name:July Salary:3200
其实int和string等预定义类型默认实现IComparable,Id的类型是int,所以可以直接进行比较。
将上面代码中CompareTo方法改为
1 public int CompareTo(object o) {
2 Employee others = (Employee)o;
3 return this.Id.CompareTo(others.Id);
4 }
效果相同。
2.如果希望以更灵活的方式进行比较,比如以工资作为键值进行排序,就需要声明一个继承自IComparer接口的比较器。
需要实现Comprae方法,返回值为int参数为2个object作为比较对象。
示例:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IComparerTest1;
namespace IComparerTest1 {
class Program {
static void Main(string[] args) {
var myList = new ArrayList();
myList.Add(new Employee(002, "Sam", 3000));
myList.Add(new Employee(001, "Mary", 2800));
myList.Add(new Employee(003, "Jick", 3800));
myList.Add(new Employee(004, "July", 3200));
myList.Sort(new SortBySalary());
foreach (var e in myList)
{
Console.WriteLine(e.ToString());
}
Console.ReadKey();
}
}
class Employee {
public int Id { get; set; }
public string Name { get; set; }
public int Salary { get; set; }
public Employee(int id, string name, int salary) {
this.Id = id;
this.Name = name;
this.Salary = salary;
}
public override string ToString() {
return "ID:" + Id + " Name:" + Name + " Salary:" + Salary;
}
}
}
class SortBySalary : IComparer {
public int Compare(object x, object y) {
Employee ex = (Employee)x;
Employee ey = (Employee)y;
return ex.Salary.CompareTo(ey.Salary);
}
Compare方法返回的是Salary比较的结果。
把比较器的示例作为参数传递给Sort方法,就可以实现该比较器。
输出结果:
ID:1 Name:Mary Salary:2800
ID:2 Name:Sam Salary:3000
ID:4 Name:July Salary:3200
ID:3 Name:Jick Salary:3800
------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------
下面是泛型IComparable<T>和IComparer<T>示例,将员工信息放进一个List<Employee>中。
IComparable<T>:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace IComparableTest3 {
class Program {
static void Main(string[] args) {
var myList = new List<Employee>();
myList.Add(new Employee(002, "Sam", 3000));
myList.Add(new Employee(001, "Mary", 2800));
myList.Add(new Employee(003, "Jick", 3800));
myList.Add(new Employee(004, "July", 3200));
myList.Sort();
foreach (var e in myList)
{
Console.WriteLine(e.ToString());
}
Console.ReadKey();
}
}
class Employee : IComparable<Employee> {
public int Id { get; set; }
public string Name { get; set; }
public int Salary { get; set; }
public Employee(int id, string name, int salary) {
this.Id = id;
this.Name = name;
this.Salary = salary;
}
public override string ToString() {
return "ID:" + Id + " Name:" + Name + " Salary:" + Salary;
}
public int CompareTo(Employee e) {
return this.Id.CompareTo(e.Id);
}
}
}
IComparer<T>:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using IComparerTest1;
namespace IComparerTest1 {
class Program {
static void Main(string[] args) {
var myList = new List<Employee>();
myList.Add(new Employee(002, "Sam", 3000));
myList.Add(new Employee(001, "Mary", 2800));
myList.Add(new Employee(003, "Jick", 3800));
myList.Add(new Employee(004, "July", 3200));
myList.Sort(new SortBySalary());
foreach (var e in myList)
{
Console.WriteLine(e.ToString());
}
Console.ReadKey();
}
}
class Employee {
public int Id { get; set; }
public string Name { get; set; }
public int Salary { get; set; }
public Employee(int id, string name, int salary) {
this.Id = id;
this.Name = name;
this.Salary = salary;
}
public override string ToString() {
return "ID:" + Id + " Name:" + Name + " Salary:" + Salary;
}
}
}
class SortBySalary : IComparer<Employee> {
public int Compare(Employee ex,Employee ey) {
return ex.Salary.CompareTo(ey.Salary);
}
}
使用泛型避免了之前非泛型中object对Employee类型的拆箱过程,减少了不必要的性能损失。