Free mag vol1 | Page 488

CHAPTER 11  ADVANCED C# LANGUAGE FEATURES } // Show all the details. Console.WriteLine(); ReflectOverAnonymousType(firstCar); ReflectOverAnonymousType(secondCar); Assuming you have called this method from within Main(). Here is the (somewhat surprising) output: My car is a Bright Pink Saab. You have a Black BMW going 90 MPH ToString() == { Make = BMW, Color = Black, Speed = 90 } Same anonymous object! Not the same anonymous object! We are both the same type! obj is an instance of: <>f__AnonymousType0`3 Base class of <>f__AnonymousType0`3 is System.Object obj.ToString() == { Color = Bright Pink, Make = Saab, CurrentSpeed = 55 } obj.GetHashCode() == -439083487 obj is an instance of: <>f__AnonymousType0`3 Base class of <>f__AnonymousType0`3 is System.Object obj.ToString() == { Color = Bright Pink, Make = Saab, CurrentSpeed = 55 } obj.GetHashCode() == -439083487 When you run this test code, you will see that the first conditional test where you call Equals() returns true and, therefore, the message “Same anonymous object!” prints out to the screen. This is because the compiler-generated Equals() method makes use of value-based semantics when testing for equality (e.g., checking the value of each field of the objects being compared). However, the second conditional test, which makes use of the C# equality operator (==), prints out “Not the same anonymous object!”, which might seem at first glance to be a bit counterintuitive. This result is due to the fact that anonymous types do not receive overloaded versions of the C# equality operators (== and !=). Given this, when you test for equality of anonymous types using the C# equality operators (rather than the Equals() method), the references, not the values maintained by the objects, are being tested for equality. Last but not least, in our final conditional test (where we examine the underlying type name), we find that the anonymous types are instances of the same compiler-generated class type (in this example, <>f__AnonymousType0`3), due to the fact that firstCar and secondCar have the same properties (Color, Make, and CurrentSpeed). This illustrates an important but subtle point: the compiler will only generate a new class definition when an anonymous type contains unique names of the anonymous type. Thus, if you declare identical anonymous types (again, meaning the same names) within the same assembly, the compiler generates only a single anonymous type definition. 428