C#值类型和引用类型的相等判断

相等的含义

对于相等的机制所有不同,这取决于比较的是引用类型还是值类型。下面分别介绍引用类型和值类型的相等性

引用类型的相等比较

System.Object定义了三种不同的方法,来比较对象的相等性:ReferenceEquals()和两个版本的Equals()。再加上比较运算符(==),实际上有4种进行比较相等的方式

ReferenceEquals()方法
命名空间: System
程序集:mscorlib.dll
语法:public static bool ReferenceEquals(Object objA, Object objB)
可以看出ReferenceEquals()是一个静态方法,确定指定的Object实例是否是相同的实例。作为静态方法,所以不能重写 例如:使用ReferenceEquals()方法比较字符串
当比较字符串时如果objA和objB是字符串,如果该字符串会暂留,ReferenceEquals方法返回true。它不执行值相等测试。在下面的示例中,因为它们是一个暂存的字符串的两个实例,str1和str2相等。 但是,str3和str4不相等,因为尽管它们是具有相同的字符串值,字符串不会暂留
比较引用地址,不去考虑其内部的数据值
Equals()方法
静态的Equals()方法
命名空间:System
程序集:mscorlib(在mscorlib.dll中)
语法:public static bool Equals(Object objA, Object objB)
静态 Equals(Object, Object) 方法指示两个对象,objA 和 objB,是否相等
它确定两个对象是否表示同一对象引用。 如果成功,该方法返回 true. 这测试与调用 ReferenceEquals 方法等效。Equals比较引用值
另外,如果 objA 和 objB 都为 null,则方法返回 true。它确定 objA 或 objB 是否null。 如果是这样,则返回false。
如果两个对象不表示同一对象引用,且均不为 null,它调用 objA。Equals(objB) 并且返回结果。 这意味着,如果objA 重写 Object.Equals(Object) 方法,该重写调用
Equals比较两个对象的数据值是否相等,但是有一个条件这两个对象属于同一种类型才能判断出最终结果

虚拟的Equals()方法
命名空间: System
程序集:mscorlib(在mscorlib.dll中)
语 法 :public virtual bool Equals(Object obj) Equals()虚拟版本的System.Object实现代码也比较引用。但因为这个方法是虚拟的,所以可以在自己的类中重写它,按值来比较对象。特别是如果希望类的实例用作字典中的键,就需要重写这个方法,以比较值。否则,根据重写
Object.GetHashCode()的方式,包含对象的字典类要么不工作,要么工作的效率非常低。在重写Equals()方法时要注意,重写的代码不会抛出异常。这是因为如果抛出异常,字典类就会出问题,一些在内部调用这个方法的.NET基类也可能出问题。Equals 是一个虚方法,允许任何类重写其实现。表示某个值(本质上可以是任何值类型)或一组值(如复数类)的任何类都应该重写 Equals。如果类型要实现 IComparable,则它应该重写 Equals。
Equals 的新实现应该遵循 Equals 的所有保证
x.Equals(x) 返回 true。
x.Equals(y) 与 y.Equals(x) 返回相同的值。
如果 (x.Equals(y) && y.Equals(z)) 返回 true,则 x.Equals(z) 返回 true。只要不修改 x 和 y 所引用的对象,x.Equals(y) 的后续调用就返回相同的值。
x.Equals(null) 返回 false
Equals的新实现不应该引发异常。建议重写 Equals 的任何类同时也重写 System.Object.GetHashCode。除了实现
Equals(对象)外,还建议所有的类为自己的类型实现 Equals(类型)以增强性能
比较运算符(==)
对于引用类型,"==“默认的行为与ReferenceEquals的行为相同,仅有两个对象指向同一个Reference的时候才返回true。但是.NET Framework中的类很多对”==“进行了重载,例如String类的”==“与Equals的行为相同,判断两个字符串的内容是否相等。所以在应用中,对于系统定义的引用类型建议不要使用”==“操作符,以免程序出现与预期不同的运行结果。 重载的运算符 == 实现不应引发异常。重载运算符”=="的任何类型还应重载运算符!=
==和Equals的区别
(1) Equals比较两个对象时必须保证两个对象的类型一致比较其值相同返回True不相同返回false
(2) Equals比较两个对象的类型不一致,不用考虑值是否一样都返回false
(3)==运算符比较值类型直接是对于其值进行比较相同为true不同为false
(4)==运算符比较引用类型直接比较的引用地址是否相同,相同为true不同为false,但是string类型除外
(5) string类型对于==运算符做了重载,结果string类型的比较方式和Equals相似

值类型的相等比较

在比较值类型的相等时,采用与引用类型相同的规则:ReferenceEquals()用于比较引用,Equals()用于比较值,比较运算可以看做是一个中间项。但最大的区别是值类型需要装箱,才能把他们转换为引用
ReferenceEquals()在应用于值类型时,总是返回false。因为调用这个方法,需要装箱

发布了117 篇原创文章 · 获赞 111 · 访问量 9661

猜你喜欢

转载自blog.csdn.net/dust__/article/details/103484860