Jenish Rabadiya
Jenish Rabadiya

Reputation: 6766

Why do the results of the Equals and ReferenceEquals methods differ even though variables are reference types?

As per this msdn documentation

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.

then why does following code results in two different result of method calls Equals method returning True and ReferenceEquals method returning false, even though the obj and obj1 is reference type as IsClass property 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));
    }
}

Output:

obj.IsClass: True

object.ReferenceEquals(obj, obj1): False

obj.Equals(obj1): True

Upvotes: 6

Views: 880

Answers (2)

Jon Hanna
Jon Hanna

Reputation: 113242

All anonymous types have an Equals override that works by:

  1. If the first object is null then return true if the second is null, false otherwise.
  2. If the second object is null, then return false.
  3. If the two objects are of different types, return false (but all anonymous objects who have the same properties which are the same name for the same type in the same object are the same type).
  4. Go through each of the properties, if calling Equals on the values the two objects have for that property is false, return false.
  5. Return true.

(They also have a GetHashCode which works by combining GetHashCode calls on each property).

If it wasn't for this, then GroupBy, Distinct, Union and similar couldn't work with anonymous properties, since each of those methods needs a concept of equality to work.

ReferenceEquals works by returning true if the two objects are in fact the same object, false if they are not.

The default for a non-anonymous object is for Equals to return the same thing as ReferenceEquals. If it was not anonymous, and something other than this was desired then the author would have provided an Equals override, and would have much greater flexibility in how they did so.

Upvotes: 3

Dennis_E
Dennis_E

Reputation: 8894

obj and obj1 refer to 2 different objects, so object.ReferenceEquals() will return false.

Equals() returns true, because the compiler implements Equals() for anonymous types. It will return true if all the properties of both objects have the same values.

Upvotes: 6

Related Questions