In my last post on Making Collections of Anonymous Types, I demonstrated how to create anonymous type collections by using a generic method as a "blueprint" factory method. Today, I will describe how this works, and conclude that it might not be a good idea to rely on this ability.

Today, I want to delve a little deeper into anonymous types and explain how this worked and what the design constraints around anonymous types are.

In general, when the compiler encounters a statement that constructs an anonymous type:

Dim x = New With {.Name = "Square", .Sides = 4}

The compiler will create a new anonymous type for this instance. However, if the compiler has already created an anonymous type that matches the fields exactly, the compiler will re-use the type definition for the anonymous type:

Dim x = New With {.Name = "Square", .Sides = 4}
Dim y = New With {.Name = "Triangle", .Sides = 3}
Debug.Assert(x.GetType() == y.GetType())

Debug.Assert(x.GetType() is y.GetType())

(thanks to Bill for pointing out my obvious mistake; teaches me to write blogs with samples at Starbucks with no VS :)

That is, the same type is used to instantiate x and y. Specifically, as long as the field names and the field types are the same, and as long as the positioning of the fields are the same, then the compiler will reuse the same type.

As an example, the following is illegal:

Dim x = New With {.Name = "Square", .Sides = 4}
x = New With {.Sides = 3, .Name = "Triangle"}

Although the shape is the same, the fields appear in different order, so the compiler treats the two types as different. Therefore, you cannot assign the second anonymous type to an instance of x (which has the first anonymous type).

In general, when the compiler encounters anonymous types that are "the same" (loosely defined above), then the compiler will reuse the types so that you get one type per assembly for anonymous types that are "the same".

A caveat: it may not be a good idea to assume and thus rely on the fact that anonymous types declared in the same assembly that are "the same" are the same type. We may choose to implement merging semantics in a different way in the future that may break this assumption. In addition, we might even think of ways to allow you to specify a blueprint without going through this "hack" so that you can write even more expressive but concise type defintions; but there are no concrete plans for that at all.

Technorati tags: , ,