Почему результаты методов Equals и ReferenceEquals различаются, даже если переменные являются ссылочными типами?

по состоянию на этой документация msdn

если текущий экземпляр является ссылочным типом, метод Equals(Object) проверяет равенство ссылок и вызывает метод Equals(Object) эквивалентен вызову метода ReferenceEquals.

тогда почему следующий код приводит к двум разным результатам вызовов методов Equals способ возврата правда и ReferenceEquals метод, возвращающий false, даже хотя ... --3--> и 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: True

2 ответов


obj и obj1 см. 2 разных объекта, поэтому object.ReferenceEquals() возвращает false.

Equals() возвращает true, потому что компилятор реализует Equals() для анонимных типов. Он вернет true, если все свойства обоих объектов имеют одинаковые значения.


все анонимные типы имеют Equals переопределить это работает:

  1. если первый объект равен null, то return true если второе значение равно null,false иначе.
  2. если второй объект равен null, то return false.
  3. если два объекта имеют разные типы, return false (но все анонимные объекты, имеющие одинаковые свойства, которые имеют одинаковое имя для одного и того же типа в одном и том же объекте, имеют одинаковый тип).
  4. Go через каждое из свойств, если вызов Equals на значениях, которые два объекта имеют для этого свойства, является false, вернуть false.
  5. Return true.

(у них также есть GetHashCode, которая работает путем объединения GetHashCode вызовы каждого свойства).

если бы не это, то GroupBy, Distinct, Union и подобное не может работать с анонимными свойствами, так как каждый из этих методов нуждается в концепции равенства работа.

ReferenceEquals работает путем возврата true если два объекта на самом деле являются одним и тем же объектом, false если они не являются.

по умолчанию для неанонимного объекта используется значение Equals чтобы вернуть то же самое, что и ReferenceEquals. Если бы он не был анонимным, и что-то другое, чем это было желательно, тогда автор предоставил бы Equals override, и будет иметь гораздо большую гибкость в том, как они это сделали.