Comparer<T> IComparer<T> IComparable<T>
Comparer<T>.Default Property
Comparer<T>.Default doesn't use your FooComparer class. It simply returns an instance of the internal class GenericComparer<T>.
This class has the constraint that T must implement IComparable<T> so it can simply delegate the calls to it Compare method to the Compare methods of the instances it gets passed.
Something like this:
internal class GenericComparer<T> : Comparer<T> where T : IComparable<T>
{
public override int Compare(T x, T y)
{
if (x != null)
{
if (y != null)
return x.CompareTo(y);
return ;
}
else
{
if (y != null)
return -;
return ;
}
} // ...
}
IComparable<T> Vs. IComparer<T>
As the name suggests, IComparable<T> reads out I'm comparable. IComparable<T> when defined for T lets you compare the current instance with another instance of same type. IComparer<T>reads out I'm a comparer, I compare. IComparer<T> is used to compare any two instances of T, typically outside the scope of the instances of T.
As to what they are for can be confusing at first. From the definition it should be clear that hence IComparable<T> (defined in the class T itself) should be the de facto standard to provide the logic for sorting. The default Sort on List<T> etc relies on this. Implementing IComparer<T> on Tdoesn't help regular sorting. Subsequently, there is little value for implementing IComparable<T> on any other class other than T. This:
class MyClass : IComparable<T>
rarely makes sense. On the other hand
class T : IComparable<T>
{
public int CompareTo(T other)
{
//....
}
}
is how it should be done.
IComparer<T> can be useful when you require sorting based on a custom order, but not as a general rule. For instance, in a class of Person at some point you might require to Sort people based on their age. In that case you can do:
class Person
{
public int Age;
} class AgeComparer : IComparer<Person>
{
public int Compare(Person x, Person y)
{
return x.Age - y.Age;
}
}
Now the AgeComparer helps in sorting a list based on Age.
var people = new Person[] { new Person { age = }, new Person(){ age = } };
people.Sort(p, new AgeComparer()); //person with age 22 comes first now.
Similarly IComparer<T> on T doesn't make sense.
class Person : IComparer<Person>
True this works, but doesn't look good to eyes and defeats logic.
Usually what you need is IComparable<T>. Also ideally you can have only one IComparable<T> while multiple IComparer<T> is possible based on different criteria.
The IComparer<T> and IComparable<T> are exactly analogous to IEqualityComparer<T> and IEquatable<T> which are used for testing equality rather than comparing/sorting; a good threadhere where I wrote the exact same answer :)
When to use IComparable<T> or IComparer<T>
Well they are not quite the same thing as IComparer<T> is implemented on a type that is capable of comparing two different objects while IComparable<T> is implemented on types that are able to compare themselves with other instances of the same type.
I tend to use IComparable<T> for times when I need to know how another instance relates to thisinstance. IComparer<T> is useful for sorting collections as the IComparer<T> stands outside of the comparison.
Quote From:
Comparer<T>.Default Property
difference between IComparable and IComparer
When to use IComparable<T> Vs. IComparer<T>
C#/.NET Little Wonders: Comparer<T>.Default
Comparer<T> IComparer<T> IComparable<T>的更多相关文章
- .NET Framework System.Array.Sort 数组类,加深对 IComparer、IComparable 以及泛型委托、匿名方法、Lambda 表达式的理解
本文内容 自定义类 Array.Sort 参考资料 System.Array.Sort 有很多对集合的操作,比如排序,查找,克隆等等,你可以利用这个类加深对 IComparer.IComparable ...
- CSharp - Comparison between IComparer and IComparable
/* Author: Jiangong SUN */ I've already written an article introducing the usage of comparer here. I ...
- Icomparer和Icomparable集合排序
c#中实现对象集合的排序可以使用ArrayList中的Sort()方法,而有比较才能谈排序,因为不是基本类型(如string ,int.double......等)所以.NET Framework不可 ...
- IComparer 与 IComparable
static void Main() { var people = new ArrayList(); people.AddRange(new ArrayList { }, }, }, } }); Co ...
- IComparer、IComparable、StringComparison枚举、CultureInfo 的用法
IEnumerable<T> 和 IEnumerator<T>.泛型版本是新式代码的首要选项. InvariantCulture:程序间.程序数据库.程序网络交互用Invari ...
- 转载:C#中的泛型
泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性.泛型为.NET框架引入了类型参数(type parameters)的概念.类型参数使得设计类和方法时,不必确定一个或多个具 ...
- C#中的泛型 【转】
C#中的泛型 泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性.泛型为.NET框架引入了类型参数(type parameters)的概念.类型参数使得设计类和方法时,不必确 ...
- C# Generic(转载)
型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性.泛型为.NET框架引入了类型参数(type parameters)的概念.类型参数使得设计类和方法时,不必确定一个或多个具体 ...
- C#中的泛型详解
泛型(generic)是C#语言2.0和通用语言运行时(CLR)的一个新特性.泛型为.NET框架引入了类型参数(type parameters)的概念.类型参数使得设计类和方法时,不必确定一个或多个具 ...
随机推荐
- C++函数调用
C++函数调用(1) 这篇博客名字起得可能太自大了,搞得自己像C++大牛一样,其实并非如此.C++有很多隐藏在语法之下的特性,使得用户可以在不是特别了解的情况下简单使用,这是非常好的一件事情.但是有时 ...
- python cookbook学习1
python cookbook学习笔记 第一章 文本(1) 1.1每次处理一个字符(即每次处理一个字符的方式处理字符串) print list('theString') #方法一,转列表 结果:['t ...
- Arduino 各种模块篇 粉尘传感器 dust sensor 空气质量检测
Testing a sensor from here. http://www.seeedstudio.com/wiki/Grove_-_Dust_Sensor It's a dust sensor. ...
- Sql Server (错误:7302)
windows server 2008 x64 sql server 2008 r2 OraClient 11g 错误提示: 解决办法:
- C语言与汇编“硬在哪里”——什么是面向硬件?
Jack:为什么说C/C++语言是偏向硬件的语言呢? 我:这是把C与java等无指针/引用类编程语言相比较而得出的结论.因为java在j2ee的框架下,写的代码仅仅是逻辑,本质上和写shell脚本没啥 ...
- MySQL SET TRANSACTION 设置事务隔离级别
1. 首先说一下autocommit 默认情况下autocommit的开关是打开的,也就是ON,查看方法 方法1. select @@[global/session].autocommit; 方法2. ...
- 话说Fetch这个API
前言: 最近在研究React这个框架,成功的成为了一名新的入坑着.用过React的都知道React的强大主要是在于它的生态的 强大,React说的再大不过也就是一个UI框架罢了.不过我们学习react ...
- 编译 MVC View
默认MVC的 View页面 不参与编译,当更改view对应model后,view编译也能通过,或者页面有错误的服务端代码时也不会报错. 那么如何在编译的时候能让View中的错误也不能通过呢.经过查找找 ...
- Unity3D【新手问题】阴影效果不显示的原因
Unity 不显示阴影的原因: 模型尺寸太大了,镜头比较远 把模型缩小,镜头一定要拉到最近才能看到 这是我遇到的问题和解决方法, 另外一定要设置 Directional light 的 shadow ...
- linux上安装mysql及简单的使用
1. 安装mysql sudo apt-get update sudo apt-get install mysql-server sudo apt-get install python-mysqldb ...