How do VB.NET anonymous types without key fields differ from C# anonymous types when compared?

anonymous-types, c#, vb.net

Solution

In C#, all properties of anonymous types behave as if they have the `Key` modifier in VB: the properties are read-only, and they're included in equality and hash code evaluation.

In VB, properties without the `Key` modifier are mutable, and are not used in the `Equals`/`GetHashCode` implementations.

From the Anonymous Type Definition documentation:

If an anonymous type declaration contains at least one key property, the type definition overrides three members inherited from `Object`: `Equals`, `GetHashCode`, and `ToString`. If no key properties are declared, only `ToString` is overridden. The overrides provide the following functionality:

`Equals` returns True if two anonymous type instances are the same instance, or if they meet the following conditions:

- They have the same number of properties.

- The properties are declared in the same order, with the same names and the same inferred types. Name comparisons are not case-sensitive.

- At least one of the properties is a key property, and the Key keyword is applied to the same properties.

- Comparison of each corresponding pair of key properties returns True.

`GetHashcode` provides an appropriately unique `GetHashCode` algorithm. The algorithm uses only the key properties to compute the hash code.

`ToString` returns a string of concatenated property values, as shown in the following example. Both key and non-key properties are included.

Problem

I'm scratching my head about this as I cannot understand why the following happens the way it does: ``` '//VB.NET Dim product1 = New With {.Name = "paperclips", .Price = 1.29} Dim product2 = New With {.Name = "paperclips", .Price = 1.29} 'compare product1 and product2 and you get false returned. Dim product3 = New With {Key .Name = "paperclips", Key .Price = 1.29} Dim product4 = New With {Key .Name = "paperclips", Key .Price = 1.29} 'compare product3 and product4 and you get true returned. '//C# var product5 = new {Name = "paperclips", Price = 1.29}; var product6 = new {Name = "paperclips", Price = 1.29}; //compare products 5 and 6 and you get true. ``` What is happening with products 1 and 2 that makes them not behave like products 5 and 6?

Original source