为什么 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 方法返回 TrueReferenceEquals 方法返回 false,即使 objobj1 是引用类型 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

objobj1 指的是 2 个不同的对象,因此 object.ReferenceEquals() 将 return false。

Equals() return 是正确的,因为编译器为匿名类型实现了 Equals()。如果两个对象的所有属性都具有相同的值,它将 return 为真。

所有匿名类型都有一个 Equals 覆盖,其工作方式是:

  1. 如果第一个对象为空,则 return true 如果第二个为空,则 false 否则。
  2. 如果第二个对象为空,则return false.
  3. 如果两个对象是不同的类型,return false(但所有匿名对象在同一个对象中具有相同属性的相同类型的相同名称是相同的类型)。
  4. 检查每个属性,如果调用 Equals 两个对象的值 属性 是 false,return false .
  5. Return 正确。

(他们还有一个 GetHashCode,它通过组合对每个 属性 的 GetHashCode 调用来工作)。

如果不是这个原因,那么 GroupByDistinctUnion 和类似的方法将无法使用匿名属性,因为这些方法中的每一个都需要一个概念工作平等。

如果两个对象实际上是同一个对象,

ReferenceEquals 通过 returning true 工作,如果不是,则 false

非匿名对象的默认值是 Equals 到 return,与 ReferenceEquals 相同。如果它不是匿名的,并且需要除此之外的其他东西,那么作者会提供一个 Equals 覆盖,并且在他们这样做的方式上会有更大的灵活性。