Effective C# Item26:使用IComarable和IComparer接口实现排序关系
来源:互联网 发布:js实现展开收起 编辑:程序博客网 时间:2024/05/02 06:11
.NET框架定义了两个接口来描述类型的排序关系:IComparable和IComparer,其中IComparable接口定义了类型的自然排序方式,IComparer则为类型提供了另外的排序方式。
我们来看下面的代码。
public struct Employee : IComparable { private string m_strName; public string Name { get { return m_strName; } set { m_strName = value; } } private int m_nAge; public int Age { get { return m_nAge; } set { m_nAge = value; } } public Employee(string name, int age) { m_strName = name; m_nAge = age; } public int CompareTo(object obj) { if (!(obj is Employee)) { throw new ArgumentException("Type Error!"); } Employee emp = (Employee)obj; return this.Name.CompareTo(emp.Name); } }
上面的代码定义了一个结构体,实现了IComparable接口,接口中方法的声明方式是int CompareTo(object obj),该方法接收一个Object对象,和当前对象进行比较,如果当前对象大于比较对象,则返回结果大于0;如果当前对象小于比较对象则返回结果为-1;如果当前对象和比较对象相同,则返回0。
下面是测试代码。
private static void Test() { Employee emp1 = new Employee("Wing", 24); Employee emp2 = new Employee("UnKnown", 25); int nResult = emp1.CompareTo(emp2); if (nResult > 0) { Console.WriteLine("emp1 is larger than emp2."); } else if (nResult < 0) { Console.WriteLine("emp1 is smaller than emp2."); } }
上述代码执行后,会在命令行中输出如下内容:emp1 is larger than emp2.
我们再来看上面的代码,其中Employee类型是一个结构体,属于值类型,但是IComparable接口的方法接收参数的类型是Object,这样我们在CompareTo()方法中必须进行装箱和拆箱的操作,才能完成比较操作。这样做对性能的影响比较大,特别是需要比较的数据非常多的时候,例如一个大数据量的集合。为了解决我们需要对上述Employee类型的代码进行修改,修改后的代码如下。
public struct Employee : IComparable { private string m_strName; public string Name { get { return m_strName; } set { m_strName = value; } } private int m_nAge; public int Age { get { return m_nAge; } set { m_nAge = value; } } public Employee(string name, int age) { m_strName = name; m_nAge = age; } int IComparable.CompareTo(object obj) { if (!(obj is Employee)) { throw new ArgumentException("Type Error!"); } Employee emp = (Employee)obj; return CompareTo(emp); } public int CompareTo(Employee emp) { return this.Name.CompareTo(emp.Name); } }
上述代码中,我们显示实现了IComparable接口,但是将访问限制符改为默认设置,即internal,同时添加了一个重载类型的CompareTo()方法, 接收一个Employee类型对象作为参数。这样,在执行Test()方法时,就会调用重载后的方法,绕过了装箱和拆箱。
注意:在实现了IComparable接口后,不需要重写Equals()方法,因为大部分情况下,Equals()方法是针对对象的引用进行比较,而IComparable接口是针对对象中的内容进行比较;因此可以出现以下的情况:两个对象调用CompareTo()方法后返回为0,但是调用Equals()方法后返回false。
另外,如果我们实现了IComparable接口,一般情况下需要对操作符进行重载,这些操作符包括:<、>、<=、>=和!=。
如果我们需要自己定制比较规则,那么我们可以通过实现IComparer接口来实现这个目标。
来看下面的代码。
public class AgeComparer : IComparer<Employee> { public int Compare(Employee x, Employee y) { return x.Age.CompareTo(y.Age); } } //Test Method private static void Test() { List<Employee> listEmp = new List<Employee>(); listEmp.Add(new Employee("Wing", 24)); listEmp.Add(new Employee("UnKnown", 25)); listEmp.Sort(); Console.WriteLine("ouput info with default sort:"); foreach (Employee emp in listEmp) { Console.WriteLine(emp.Name); } Console.WriteLine("output info with specific sort:"); AgeComparer comparer = new AgeComparer(); listEmp.Sort(comparer); foreach (Employee emp in listEmp) { Console.WriteLine(emp.Name); } }
上面的代码中,首先定义了一个实现了IComparer接口的类型,该类型的Compare()方法中,以Employee的Age作为比较的依据。然后定义了一个测试方法,定义了一个元素类型是Employee类型的List,然后以两种方式对List进行排序,并输出排序后的结果。
上面Test()方法的执行结果如下所示。
综上,IComparable接口和IComparer接口为类型实现排序关系提供了两种标准的机制,IComparable接口应该用于为类型实现最自然的排序关系,而ICpmparer接口则用于定制排序的方式。
- Effective C# Item26:使用IComarable和IComparer接口实现排序关系
- Effective C# 使用IComparable和IComparer接口实现排序关系
- C# List<> 实现 IComparer 接口 排序
- Effective C# 原则26:用IComparable和IComparer实现对象的顺序关系
- 《Effective C#》 Item 26:对需要排序的对象实现IComparable和IComparer接口
- 使用IComparable和IComparer接口对集合进行排序
- C#中IComparable<T>和IComparer<T>接口的使用
- 结合IComparer接口实现对ListBox排序
- C#比较器接口IComparer的实现
- C#中IComparer和IComparable接口
- 笔记(显示实现接口,实现IComparable,IComparer接口来排序)
- c# 接口IComparer<T>
- C#中对对象的排序重写IComparer接口
- C#笔记25:比较和排序(IComparable和IComparer以及它们的泛型实现)
- C#中IComparable接口和IComparer接口应用的实例
- IComparable和Icomparer接口
- IComparable和IComparer接口
- c# 实现IComparable、IComparer接口、Comparer类的详解
- Access to the requested object is only available from the local network phpmyadmin
- poj 3984 迷宫问题 (bfs入门)
- 关于LDA模型
- 【学习笔记】tablelayout等分控件
- InitializeCriticalSectionAndSpinCount
- Effective C# Item26:使用IComarable和IComparer接口实现排序关系
- 梯度下降算法
- Note for 20140725
- “特产百科”即将面世 已进入内测阶段
- 获取文件路径
- 的算法京东方
- Android使用主题配置文件,去掉程序启动界面的短暂黑屏。
- 状态栏字体颜色
- KMP算法心得