I'm just wondering why designers of the language decided to implement Equals on anonymous types similarly to Equals
on value types. Isn't it misleading?
public class Person
{
public string Name { get; set; }
public int Age { get; set; }
}
public static void ProofThatAnonymousTypesEqualsComparesBackingFields()
{
var personOne = new { Name = "Paweł", Age = 18 };
var personTwo = new { Name = "Paweł", Age = 18 };
Console.WriteLine(personOne == personTwo); // false
Console.WriteLine(personOne.Equals(personTwo)); // true
Console.WriteLine(Object.ReferenceEquals(personOne, personTwo)); // false
var personaOne = new Person { Name = "Paweł", Age = 11 };
var personaTwo = new Person { Name = "Paweł", Age = 11 };
Console.WriteLine(personaOne == personaTwo); // false
Console.WriteLine(personaOne.Equals(personaTwo)); // false
Console.WriteLine(Object.ReferenceEquals(personaOne, personaTwo)); // false
}
At first glance, all printed boolean values should be false. But lines with Equals
calls return different values when Person
type is used, and anonymous type is used.
Best Answer
Anonymous type instances are immutable data values without behavior or identity. It doesn't make much sense to reference-compare them. In that context I think it is entirely reasonable to generate structural equality comparisons for them.
If you want to switch the comparison behavior to something custom (reference comparison or case-insensitivity) you can use Resharper to convert the anonymous type to a named class. Resharper can also generate equality members.
There is also a very practical reason to do this: Anonymous types are convenient to use as hash keys in LINQ joins and groupings. For that reason they require semantically correct
Equals
andGetHashCode
implementations.