在00-1010.net,IComparableT是最常用的比较界面。

如果某个类型的实例需要与该类型的其他实例进行比较或排序,那么这个类型可以通过实现IComparableT接口来实现这个目标。

IComparableT只提供一种方法:

让我们看一个使用字符串的例子,因为字符串实现了接口:

c是什么意思网络用语(c语言中文网)-编程之家

结果是:

字符串按位字母比较,“A”小于“B”,所以上面的str1应该小于str2。

虽然CompareTo方法返回int类型,但比较结果可能有三种情况:

X==yxyy通过上面的例子,我们可以看到:

关于帕累托(y),

如果x==y,则结果=0如果x是y,则结果0如果x是y,则结果0我们可以重构代码并提取一个低级方法来促进逻辑重用:

c是什么意思网络用语(c语言中文网)-编程之家

顺便说一下,string不实现==等运算符。

(同Internationalorganizations)国际组织

所有基元类型都实现IComparableT。

因此,使用上述方法,您还可以比较原始数据类型:

c是什么意思网络用语(c语言中文网)-编程之家

当然,这些类型也可以使用运算符,例如:

c是什么意思网络用语(c语言中文网)-编程之家

String没有实现这些运算符,所以这样写是错误的:

00-1010直接看图:

c是什么意思网络用语(c语言中文网)-编程之家

其中System.object不支持比较,因为对于大多数类型来说,比较和排序它们的实例是没有意义的。

比如3 4,这是合理的;而提交按钮取消按钮,没有意义;这个佣金是另一个佣金,没有意义。

对于等式,IEquatableT只是对象中那些Equals方法的补充。比较而言,IComparableT是主要方式。

其他方式都有对应。

下面两个黄色的通过插件。

方式“实现的,这里只提一下,不介绍了。

比较性 只比较值

c是什么意思网络用语(c语言中文网)-编程之家

判断相等性的时候,可能判断的是引用相等或者是值相等。

而进行比较排序的时候,其比较的只能是值,因为对引用进行比较排序是没有意义的。

而==和!=操作符可以为原始数据类型和引用类型来使用,而>, <, >=, <= 只能用于原始数据类型。

在自定义类型上实现比较

其实我通常不在我的类型上去实现IComparable<T>,包括引用类型和原始类型。

因为是这样的,比如说有一个Person(人)这个类型,我想对它排序,按照年龄排序,可以;按照姓名排序,也可以;按照身高排序,也可以;但是没有任何一种排序对人来说是最理所当然的。

更好的办法是实现某种比较器。

但是有时候还是需要实现IComparable<T>,那么下面就讲一下怎么做。

值类型

Person Struct:

c是什么意思网络用语(c语言中文网)-编程之家

如果直接使用我们之前的方法,则会报错:

c是什么意思网络用语(c语言中文网)-编程之家

因为它没实现IComparable<T>接口。

使用大于号小于号的话,也会报错:

c是什么意思网络用语(c语言中文网)-编程之家

因为这个类型也没有实现比较操作符。

实现IComparable<T>接口

c是什么意思网络用语(c语言中文网)-编程之家

很简单,直接调用了字段Height的CompareTo方法,因为int类型实现了IComparable<T>接口。

实现比较操作符

一共四个操作符:<, >, <=, >=,必须都得实现。

代码是:

c是什么意思网络用语(c语言中文网)-编程之家

这个很简单就不解释了。

现在代码不会报错了:

c是什么意思网络用语(c语言中文网)-编程之家

其运行结果是:

c是什么意思网络用语(c语言中文网)-编程之家

运行OK了,看似没问题,然后,还有一个问题:

c是什么意思网络用语(c语言中文网)-编程之家

使用等号判断相等性的代码会报错。

如果你不是用==操作符的话,那么代码是没问题的,也是可以进行比较的,也没人强制要求实现==和!=操作符。但是这很奇怪!因为你说 p1 > p2,这个成立,然后再说 p1 != p2这个就编译错误,那就不合理了。

所以,如果你实现了比较操作符,那么相等性操作符也应该一同实现了:

c是什么意思网络用语(c语言中文网)-编程之家

那么既然==和!=都实现了,那么其它的相等性判断方法也应该一同实现:

object.Equals()object.GetHashCode()IEquatable<T>

看起来挺麻烦,但这只是一个struct,还是相对简单的。。。。

但针对struct,其实还没完,还有一个非泛型的IComparable接口,泛型出现之前,一直都是用这个接口的。

这个接口现在来说没什么用了,但是如果有其它遗留的老代码需要使用你这个struct,你可能还需要把这个接口实现一下。。。

引用类型

引用类型除了需要考虑上面struct考虑的那些东西外,还需要考虑更多的东西。

首先,需要在CompareTo里面检查是否为null,和类型检查。

而如果Person是一个没有seal的class,那问题就更大了,以前文章里提到的OOP继承问题、类型安全问题、相等性问题将全部出现。因为类型安全和比较性还是没法一起很愉快的工作。反正会很混乱。。。

所以如果事seal的class,那么在其上实现比较性的话还勉强可以接受;否则的话,祝好运。。。

泛型

之前在相等性的文章里,提到过,针对泛型代码来说,==和!=操作符不能很好的工作,而object.Equals()却可以。

这点在比较性里面也是一样的。针对泛型的比较,你需要使用IComparable<T>.CompareTo()方法,而不是比较的操作符>, <, >=, <=等(即使实现了比较操作符)。

如果我把之前的方法代码改成使用比较操作符:

c是什么意思网络用语(c语言中文网)-编程之家

那么就会报错,因为无法约束泛型实现了某些操作符。。。但可以考虑在接口里面实现比较操作符。。。

但是实现比较性的话:

实现IComparable<T>接口也可选去实现比较操作符。