C#之相等比较
C#中的对象都继承自System.Object对象,分为引用类型和值类型两种,所以对象的相等比较而言就分两种,一种是比较引用,一种是比较值。System.Object默认提供了三个方法来进行对象的相等比较:静态的ReferenceEquals()和Equals()的两个版本,加上“==”运算符共有四种来进行对象相等比较的方法。
相等比较的方法:静态的ReferenceEquals()、Equals()静态方法、Equals()虚方法(子类可以去重写)和“==”运算符。
相等比较分类:引用类型比较(类的实例)、值类型比较(基本数据类型,结构或者枚举的实例)。
但对于引用类型和值类型而言,同一个方法它们的内部比较逻辑是不一样的,下面进行下简单的介绍。
一、引用类型相等比较
1、静态的ReferenceEquals()
ReferenceEquals()是一个静态方法,比较两个对象是否引用自同一个地址,是则返回true,否则返回false
调用方法:ReferenceEquals(obj1,obj2)
比较原则:1)、obj1和obj2同为null,则返回true
2)、obj1和obj2只有一个为null,则返回false
3)、obj1和obj2均不为null时,比较两个对象的引用地址,是则返回true,不是则返回false
例子:
SomeClass x,y;
x = new SomeClass();
y = new SomeClass();
z = y;
Boolean result1 = ReferenceEquals(null,null); //return true
Boolean result2 = ReferenceEquals(null,x); //return false
Boolean result3 = ReferenceEquals(x,y); //return false
Boolean result4 = ReferenceEquals(y,z); //return true
2、虚拟的Equals()方法
System.Object()的虚拟的Equals()方法也是比较引用的,但是因为它是虚拟的,所以继承的子类可以重写该方法以实现按值来比较对象,在重写Equals()方法时最好重写对象的GetHashCode()方法.
3、静态的Equals()方法
Eauals()静态方法的比较原则是按照引用的方式比较,再调用对象的Equals()方法的实例版本进行比较,所以在重写对象的Equals()方法时,其实已经间接的重写了静态的Equals()方法。
调用方法:Equals(obj1,obj2)
比较原则:1)、obj1和obj2均为null,则返回true
2)、obj1和obj2中只有一个为null,则返回false
3)、如果obj1和obj2两个引用不指向同一个对象,则返回false
4)、如果obj1和obj2两个引用指向同一个对象,则调用它们的Equals()方法的实例版本进行比较
4、“==”比较运算符
在默认情况下,==运算符对引用类型比较的是两个对象指向的引用是否是同一个对象,但是作为一个自定义的复杂类,可以自己重写适合自己的“==”运算符,在重写“==”时必须同时重写“!=”运算符。
二、值类型相等比较
1、静态的ReferenceEquals()
ReferenceEquals()方法用于比较引用,在比较之前,C#会先通过装箱技术对每个值类型参数进行分别装箱,这样ReferenceEquals()方法进行比较时得到的结果永远时false,所以用ReferenceEquals()来比较值类型是没有什么意义的。
2、虚拟的Equals()方法、静态的Equals()方法和“==”运算符
对于值类型,这三个方法默认都是进行值比较的。