C# and VB Continue to Diverge
When VB.NET and C# were first released, they were often thought of as the same language with a different syntax and minor differences. As time goes on, these differences are becoming more pronounced. For example, their treatment of anonymous types is worlds apart.
In order to support data structures like hash tables and query operations like grouping, anonymous types created by LINQ must provide stable hash codes. Hash codes are normally created from the fields in the object.
The early versions of anonymous types were mutable. Or in other words, the values contained by the object could be altered. Changing these values would change the hash code, which would in turn break any hash table or dictionary that the object happened to be stored in.
Taking the direct route, the C# team made anonymous types immutable. If the object cannot be altered, then the hash code will never change either. The usually rules for immutable types were put into place such as no default constructors and only getters for properties.
The VB team was not so willing to give up the ability to modify anonymous classes. Paul Vick writes
In looking at this problem, though, we didn't want to throw the baby out with the bathwater. Anonymous types are somewhat limited at the moment because they cannot be named, but you can use late binding to work with them even outside of the context in which they were declared. And future features that we're interested in exploring, such as nominal anonymous types and dynamic interfaces, may make anonymous types even more useful. As such, it seemed too drastic to simply make them immutable, especially because this would be a one-way decision--once they were immutable, compatibility would make it extremely difficult to make them mutable again in the future if it become more desirable to do so.
They choose a solution that is more complex, but also gives the developer more flexibility. When creating anonymous classes, programmers can use the modifier "Key" to indicate which fields are immutable. In addition to making the property read-only, the hash code function will only use these 'key' fields to generate the hash code. As a result, the hash codes are guaranteed to be stable. Fields will also be automatically marked as Key by the compiler when used in joins and group by clauses.
The reason VB and C# can use different implementations is that anonymous types are a compiler feature. The CLR itself doesn't have any notion of anonymous types and sees them as normal classes with automatically generated names.
Like much of the VB syntax, this functionality is expected to not be available until Orcas Beta 2.
Ronny Kohavi Dec 12, 2013