为什么 Equals 和 ReferenceEquals 方法的结果不同,即使变量是引用类型?
Why do the results of the Equals and ReferenceEquals methods differ even though variables are reference types?
根据 this msdn 文档
If the current instance is a reference type, the Equals(Object) method tests for reference equality, and a call to the Equals(Object) method is equivalent to a call to the ReferenceEquals method.
那么为什么下面的代码会导致方法调用的两个不同结果 Equals
方法返回 True 和 ReferenceEquals
方法返回 false,即使 obj
和 obj1
是引用类型 IsClass
属性 returns 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: True
object.ReferenceEquals(obj, obj1): False
obj.Equals(obj1): True
obj
和 obj1
指的是 2 个不同的对象,因此 object.ReferenceEquals()
将 return false。
Equals()
return 是正确的,因为编译器为匿名类型实现了 Equals()
。如果两个对象的所有属性都具有相同的值,它将 return 为真。
所有匿名类型都有一个 Equals
覆盖,其工作方式是:
- 如果第一个对象为空,则 return
true
如果第二个为空,则 false
否则。
- 如果第二个对象为空,则return
false
.
- 如果两个对象是不同的类型,return
false
(但所有匿名对象在同一个对象中具有相同属性的相同类型的相同名称是相同的类型)。
- 检查每个属性,如果调用
Equals
两个对象的值 属性 是 false
,return false
.
- Return 正确。
(他们还有一个 GetHashCode
,它通过组合对每个 属性 的 GetHashCode
调用来工作)。
如果不是这个原因,那么 GroupBy
、Distinct
、Union
和类似的方法将无法使用匿名属性,因为这些方法中的每一个都需要一个概念工作平等。
如果两个对象实际上是同一个对象,ReferenceEquals
通过 returning true
工作,如果不是,则 false
。
非匿名对象的默认值是 Equals
到 return,与 ReferenceEquals
相同。如果它不是匿名的,并且需要除此之外的其他东西,那么作者会提供一个 Equals
覆盖,并且在他们这样做的方式上会有更大的灵活性。
根据 this msdn 文档
If the current instance is a reference type, the Equals(Object) method tests for reference equality, and a call to the Equals(Object) method is equivalent to a call to the ReferenceEquals method.
那么为什么下面的代码会导致方法调用的两个不同结果 Equals
方法返回 True 和 ReferenceEquals
方法返回 false,即使 obj
和 obj1
是引用类型 IsClass
属性 returns 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: True
object.ReferenceEquals(obj, obj1): False
obj.Equals(obj1): True
obj
和 obj1
指的是 2 个不同的对象,因此 object.ReferenceEquals()
将 return false。
Equals()
return 是正确的,因为编译器为匿名类型实现了 Equals()
。如果两个对象的所有属性都具有相同的值,它将 return 为真。
所有匿名类型都有一个 Equals
覆盖,其工作方式是:
- 如果第一个对象为空,则 return
true
如果第二个为空,则false
否则。 - 如果第二个对象为空,则return
false
. - 如果两个对象是不同的类型,return
false
(但所有匿名对象在同一个对象中具有相同属性的相同类型的相同名称是相同的类型)。 - 检查每个属性,如果调用
Equals
两个对象的值 属性 是false
,returnfalse
. - Return 正确。
(他们还有一个 GetHashCode
,它通过组合对每个 属性 的 GetHashCode
调用来工作)。
如果不是这个原因,那么 GroupBy
、Distinct
、Union
和类似的方法将无法使用匿名属性,因为这些方法中的每一个都需要一个概念工作平等。
ReferenceEquals
通过 returning true
工作,如果不是,则 false
。
非匿名对象的默认值是 Equals
到 return,与 ReferenceEquals
相同。如果它不是匿名的,并且需要除此之外的其他东西,那么作者会提供一个 Equals
覆盖,并且在他们这样做的方式上会有更大的灵活性。