Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Why does the Equals implementation for anonymous types compare fields?

Tags:

c#

c#-3.0

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.

like image 361
dragonfly Avatar asked Aug 25 '12 16:08

dragonfly


People also ask

Why we use anonymous types in C#?

Anonymous types provide a convenient way to encapsulate a set of read-only properties into a single object without having to explicitly define a type first. The type name is generated by the compiler and is not available at the source code level. The type of each property is inferred by the compiler.

Why anonymous types are better than tuples?

Tradeoffs. You might want to always use ValueTuple over Tuple, and anonymous types, but there are tradeoffs you should consider. The ValueTuple types are mutable, whereas Tuple are read-only. Anonymous types can be used in expression trees, while tuples cannot.

When you define an anonymous type the compiler converts that type into a?

The compiler generates a name for each anonymous type. If two or more anonymous type objects are defined in the same assembly and the sequence of properties are same in terms of names and types than the compiler treats both as same object instances of type.

What is the difference between an anonymous type and a regular data type?

The compiler gives them a name although your application cannot access it. From the perspective of the common language runtime, an anonymous type is no different from any other reference type, except that it cannot be cast to any type except for object.


2 Answers

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 and GetHashCode implementations.

like image 103
usr Avatar answered Sep 17 '22 13:09

usr


For the why part you should ask the language designers...

But I found this in Eric Lippert’s article about Anonymous Types Unify Within An Assembly, Part Two

An anonymous type gives you a convenient place to store a small immutable set of name/value pairs, but it gives you more than that. It also gives you an implementation of Equals, GetHashCode and, most germane to this discussion, ToString. (*)

Where the why part comes in the note:

(*) We give you Equals and GetHashCode so that you can use instances of anonymous types in LINQ queries as keys upon which to perform joins. LINQ to Objects implements joins using a hash table for performance reasons, and therefore we need correct implementations of Equals and GetHashCode.

like image 20
nemesv Avatar answered Sep 20 '22 13:09

nemesv