为什么即使变量是引用类型,Equals和ReferenceEquals方法的结果也不同
本文关键字:方法 ReferenceEquals 结果 Equals 变量 引用类型 为什么 | 更新日期: 2023-09-27 18:24:00
根据本msdn文档
如果当前实例是引用类型,则Equals(Object)方法测试引用相等性,并且对Equals)方法的调用等效于对ReferenceEquals方法的调用。
那么,为什么以下代码会导致方法调用的两个不同结果Equals
方法返回True和ReferenceEquals
方法返回false,即使obj
和obj1
是引用类型,因为IsClass
属性返回True。
using System;
public class Program
{
public static void Main()
{
var obj = new { a = 1, b = 1 };
var obj1 = new { a = 1, b = 1 };
Console.WriteLine("obj.IsClass: " + obj.GetType().IsClass);
Console.WriteLine("object.ReferenceEquals(obj, obj1): " + object.ReferenceEquals(obj, obj1));
Console.WriteLine("obj.Equals(obj1): " + obj.Equals(obj1));
}
}
输出:
obj.IsClass:真
object.ReferenceEquals(obj,obj1):错误
obj.Equals(obj1):真
obj
和obj1
引用了两个不同的对象,因此object.ReferenceEquals()
将返回false。
Equals()
返回true,因为编译器为匿名类型实现了Equals()
。如果两个对象的所有属性都具有相同的值,则返回true。
所有匿名类型都有一个Equals
覆盖,其工作方式为:
- 如果第一个对象为空,则如果第二个对象为零则返回
true
,否则返回false
- 如果第二个对象为null,则返回
false
- 如果这两个对象的类型不同,则返回
false
(但所有具有相同属性的匿名对象都是相同类型的,并且在同一对象中具有相同的名称) - 遍历每个属性,如果对两个对象为该属性所具有的值调用
Equals
是false
,则返回false
- 返回true
(它们还有一个GetHashCode
,它通过组合对每个属性的GetHashCode
调用来工作)。
如果不是这样,那么GroupBy
、Distinct
、Union
和类似的方法就不能使用匿名属性,因为这些方法中的每一个都需要相等的概念才能工作。
如果两个对象实际上是同一个对象,则ReferenceEquals
通过返回true
来工作,如果不是,则返回false
。
非匿名对象的默认值是Equals
返回与ReferenceEquals
相同的内容。如果它不是匿名的,并且需要其他东西,那么作者会提供Equals
覆盖,并且在如何做到这一点上会有更大的灵活性