2015-11-23 3 views
6

В соответствии с this MSDN документацииПочему результаты методов Equals и ReferenceEquals отличаются, хотя переменные являются ссылочными типами?

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

тогда почему следующий код приводит к двум различным результатам вызовов метода Equals метод, возвращающий Правда и ReferenceEquals метод возвращения ложным, даже несмотря на то, obj и obj1 является ссылочным типом, как IsClass свойство возвращает истину.

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): Правда

+2

Анонимные типы переопределяют Equals и GetHashCode –

+0

Подробнее о том, с какой страницей вы связались - «Поскольку класс Object является базовым классом для всех типов в .NET Framework, метод Object.Equals (Object) предоставляет значение по умолчанию сравнение равенства для всех других типов. Однако типы часто переопределяют метод Equals для реализации равенства ценности ». –

+0

Я пропустил то, что анонимные объекты переопределяют одинаковый метод. @JenishRabadiya btw, это было очевидно для моего собственного xD, поэтому я забыл упомянуть об этом. –

ответ

6

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

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

+0

Спасибо! будет принимать ответ в ближайшие пару минут. :) –

3

Все анонимные типы имеют Equals переопределение, который работает по:

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

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

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

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

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

Смежные вопросы