C#中的IComparable 和 IComparer 接口,实现列表中的对象比较和排序
借豆瓣某博主的话先对这两个接口进行一个解释:
  IComparable在要比较的对象的类中实现,可以比较该对象和另一个对象
  
IComparer在一个单独的类中实现,可以比较任意两个对象。
如果已经支持 IComparer 的类型 (如 字符串 或 整数) 的数组可以对该数组进行排序而无需提供 IComparer 任何显式引用。在这种情况下该数组的元素强制转换为您 IComparer(Comparer.Default) 的默认实现。但是,如果您想要提供您自定义的对象进行排序或比较功能,则必须实现这些接口的一项或两项。
IComparable
  IComparable 的作用是提供了一种比较两个对象的特定类型的方法。这是必需的如果您想要为对象提供任何排序功能。视为 IComparable 提供您的对象的默认排序次序。例如对于如果您有一个您的类型的对象的数组,并在该数组上调用 Sort 方法 IComparable 在排序过程中提供对象的比较。实现 IComparable 界面时, 必须实现 CompareTo 方法,如下所示:
int IComparable.CompareTo(object obj)
{
car c=(car)obj;
return String.Compare(this.make,c.make);
}
方法中的比较是不同的要比较的值数据类型 depending on。因为选择了比较属性是字符串,此示例中使用 String.Compare。
IComparer
  IComparer 的角色是提供附加的比较机制。例如对于您可能需要提供几个字段或属性,在类中的顺序升序和降序在同一字段或两者。
  使用 IComparer 是一个包含两个步骤的过程:
   1)声明一个类实现 IComparer,然后实现比较方法: 
  
private class sortYearAscendingHelper : IComparer
{
int IComparer.Compare(object a, object b)
{
car c1=(car)a;
car c2=(car)b;
if (c1.year > c2.year)
return ;
if (c1.year < c2.year)
return -;
else
return ;
}
}
2)声明一个返回 IComparer 对象的实例的方法:
public static IComparer sortYearAscending()
{
return (IComparer) new sortYearAscendingHelper();
}
在此的示例为第二个参数时,调用重载的 Array.Sort 方法接受 IComparer 使用对象。IComparer 的使用并不限于数组。它将被接受作为许多不同的集合和控件类中的参数。
而在List<T>中已经有了排序的方法了.Sort(参数),参数为比较器,共有四种重载。
| Name | Description | 
|---|---|
 Sort() | 
Sorts the elements in the entireList<T> using the default comparer. | 
 Sort(Comparison<T>) | 
Sorts the elements in the entireList<T> using the specifiedSystem.Comparison<T>. | 
 Sort(IComparer<T>) | 
Sorts the elements in the entireList<T> using the specified comparer. | 
 Sort(Int32, Int32, IComparer<T>) | 
Sorts the elements in a range of elements in List<T> using the specified comparer. | 
第一种就是默认排序,只对常见的类型比如int,float,double,string等可以自身比较的类型。默认升序排序。、
第二种为Comparison<T>,此处是指定比较的模式,只需要写一个简单的比较函数即可,比如:
private static int CompareDinosByLength(string x, string y)//这里的参数一般是要比较的List内的元素
{
if (x == null)
{
if (y == null)
return ;
else
return -;
}
else
{
if (y == null)
return ;
else
{
int retval = x.Length.CompareTo(y.Length);
if (retval != )
return retval;
else
return x.CompareTo(y);
}
}
} int static Main()
{
List<string> dinosaurs = new List<string>();
dinosaurs.Add("Pachycephalosaurus");
dinosaurs.Add("Amargasaurus");
dinosaurs.Add("");
dinosaurs.Add(null);
dinosaurs.Add("Mamenchisaurus");
dinosaurs.Add("Deinonychus");
Display(dinosaurs); Console.WriteLine("\nSort with generic Comparison<string> delegate:");
dinosaurs.Sort(CompareDinosByLength);
}
第三种相对复杂一点,需要新设置一个比较器,并且实现接口,实现其中的函数,比如:
public class DinoComparer: IComparer<string>
{
public int Compare(string x, string y)
{
if (x == null)
{
if (y == null)
return ;
else
return -;
}
else
{
if (y == null)
return ;
else
{
int retval = x.Length.CompareTo(y.Length); if (retval != )
return retval;
else
return x.CompareTo(y);
}
}
}
} public class Example
{
public static void Main()
{
List<string> dinosaurs = new List<string>();
dinosaurs.Add("Pachycephalosaurus");
dinosaurs.Add("Amargasaurus");
dinosaurs.Add("Mamenchisaurus");
dinosaurs.Add("Deinonychus"); DinoComparer dc = new DinoComparer();
dinosaurs.Sort(dc);
}
第四种则是在第三中的基础之上添加指定的索引内的排序。
那么在写好的比较器上怎么实现逆转排序呢?就是如果原先是正序,那么想要反序如何?看排序函数的返回值都是int类型,所以想要反序只需要在调用时前面加 - (负)即可。一般正序排序的返回值:-1代表前小后大,0代表相等,1代表前大后小,排序效果为从小到大。
调用时是使用函数名调用,所以必须写两个函数了。使用Linq的排序可以使用前加符号的方式:http://www.tuicool.com/articles/aqU3eee
C#中的IComparable 和 IComparer 接口,实现列表中的对象比较和排序的更多相关文章
- [0] 关于IComparable和IComparer接口和Comparer类
		
关于IComparable和IComparer接口 和 Comparer类 IComparable和ICompareframeworkr接口是.net 中比较对象的标准方式,这两个接口之间的区别如下: ...
 - 对象的比较与排序:IComparable和IComparer接口
		
IComparable和ICompare 接口是.net framework 中比较对象的标准方式,这两个接口提供一个返回值类似(大于0 等于0 小于0)的比较方法,二者区别如下: . ICompar ...
 - c# 实现IComparable、IComparer接口、Comparer类的详解
		
在默认情况下,对象的Equals(object o)方法(基类Object提供),是比较两个对象变量是否引用同一对象.我们要必须我自己的对象,必须自己定义对象比较方式.IComparable和ICom ...
 - 数组自定义排序:IComparable和IComparer接口
		
首先先说一下IComparable和IComparer的区别,前者必须在实体类中实现,后者可以单独出现在一个排序类中,即此类只包含一个compare方法. Array类使用快速算法对数组中的元素进行排 ...
 - IComparable和IComparer接口
		
C#中,自定义类型,支持比较和排序,需要实现IComparable接口.IComparable接口存在一个名为CompareTo()的方法,接收类型为object的参数表示被比较对象,返回整型值:1表 ...
 - C# 中的IComparable和IComparer
		
前言 在开发过程中经常会遇到比较排序的问题,比如说对集合数组的排序等情况,基本类型都提供了默认的比较算法,如string提供了按字母进行排序,而int整数则是根据整数大小进行排序.但是在引用类型中(具 ...
 - C#的 IComparable 和 IComparer接口及ComparableTo方法的 区别(非常重要)
		
(1)https://blog.csdn.net/ios99999/article/details/77800819 C# IComparable 和 IComparer 区别 (2)https:// ...
 - 实现IComparable、IComparer接口
		
using System;using System.Collections.Generic; public class MyClass{ public class Employee:IComparab ...
 - c# IComparable与IComparer接口
 
随机推荐
- MVC – 14.ajax异步请求
			
14.1.配置文件 14.2.AjaxHelper – 异步链接按钮 14.3.AjaxHelper – 异步表单 AjaxOptions常见属性: 14.4.AjaxOptions对象生成[对应]触 ...
 - SQL——触发器——插入触发器——边学边项目写的。
			
需求: 项目表项目编码触发器编写 为项目表DwProject编写触发器,目的为当创建新项目时,且ProjectNo 为Null或空字符串时,自动创建项目编号,编号格式为4位年号,2位月份,2位顺序号, ...
 - 手机站点动态效果插件TouchSlide
			
今天看到TouchSlide插件,觉得非常不错,关于使用情况请看demo,下载地址:http://www.superslide2.com/TouchSlide/downLoad.html
 - C-线性顺序表的增删改查
			
闲来无事,练练手,写点C代码,对于线性表的简单操作.编辑工具Notpad++,编译工具tcc. /* *the sequence of the list *author:JanneLee *data: ...
 - JAVA和PYTHON同时实现AES的加密解密操作---且生成的BASE62编码一致
			
终于有机会生产JAVA的东东了. 有点兴奋. 花了一天搞完.. java(关键key及算法有缩减): package com.security; import javax.crypto.Cipher; ...
 - .Learning.Python.Design.Patterns.2nd.Edition之单实例模式
			
可以慢慢理解.. 对照JAVA class Singleton(object): def __new__(cls): if not hasattr(cls, 'instance'): cls.inst ...
 - 数据结构之图 Part1
			
Part 1 预计使用7天的时间来过掉图相关的数据结构.第一天主要是一天图的基本概念,熟练掌握定义是一切交流和沟通的基础. 1定义 1.1图 有穷非空顶点,外加边. G(V,E) Graph Vert ...
 - hdu 4734 数位dp
			
给一个数A (十进制表示形式为AnAn-1An-2 ... A2A1,定义函数 F(x) = An * 2n-1 + An-1 * 2n-2 + ... + A2 * 2 + A1 * 1,给一个B, ...
 - VR 相关专业词汇
			
最近在看 SIGGRAPH2015 有关 VR Display and Interaction 的几篇文章,之前从来没看过有关方面的 paper,一看才发现专业词汇太多了,根本不懂啊,幸亏 Paper ...
 - 介绍linux下vi命令的使用
			
功能最强大的编辑器之一——vivi是所有UNIX系统都会提供的屏幕编辑器,它提供了一个视窗设备,通过它可以编辑文件.当然,对UNIX系统略有所知的人,或多或少都觉得vi超级难用,但vi是最基本的编辑器 ...
 
			
		