title: How are Equals and GetHashCode implemented on anonymous types?
body: <p>The Help says this:</p>
  
  <blockquote>
    <p>Anonymous types are class types that derive directly from object, and
    that cannot be cast to any type except object. The compiler provides a
    name for each anonymous type, 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.</p>
    
    <p>If two or more anonymous object initializers in an assembly specify a
    sequence of properties that are in the same order and that have the
    same names and types, the compiler treats the objects as instances of
    the same type. They share the same compiler-generated type
    information.</p>
    
    <p>Because the Equals and GetHashCode methods on anonymous types are
    defined in terms of the Equals and GetHashCode methods of the
    properties, two instances of the same anonymous type are equal only if
    all their properties are equal.</p>
  </blockquote>
  
  <p>These things are true, but how? The reference source shows explicitly how objects are compared (<code>ReferenceEquals</code>) and a type that 'derives directly from object' cannot have this special behaviour. It doesn't match the behavour of <code>Equals</code> in <code>ValueType</code> either.</p>
  
  <p>So how is it done? How can anonymous types override <code>Equals()</code> and <code>GetHashCode()</code> without any visible overrides?</p>