Making Collections of Anonymous Types

One of the cool but lesser known features introduced in VB9 is the anonymous type. What exactly are anonymous types? They are simply unnamed types that you can define easily:

 Dim x = New With { .Name = "timng", .Age = 27 ]

The above statement instructs the compiler to create a new anonymous type with two fields; one field called "Name" with the value "timng" and the second field called "Age" with the value 27. (In reality, the compiler creates fields with internal names, and exposes properties called "Name" and "Age" instead).

For this post, I won't discuss the internals of anonymous types; I'll leave that for another post. Rather, I want to address the question, "if the anonymous type is unnamed, how can I make a collection of anonymous types?" The techniques used here can be extended to a variety of scenarios.

Typically, if you wanted to create, say, a list of strings, you would write code like this:

 Dim Names = New List(Of String)

Here, the compiler will know how to instantiate the generic type List(Of T) since you specifically told it to make a list of strings. What about anonymous types? You can't specify a type because it's unnamed. You can always use object, but that that has undesirable (at times) semantics because it becomes late bound and you don't get intellisense.

Rather, we can make use of generic type inference. Let's define a method MakeList:

 Function MakeList(Of T)(instance As T) As List(Of T)
    Return New List(Of T)
End Sub

How does this method work? It is a generic method with one "template" parameter that is unused. The sole purpose of the parameter is to cause the compiler to do type inference like so:

 Dim list = MakeList(New With {.Name = "timng", .Age = 27})

Since no type was provided for the type parameter T, the compiler tries to infer the type based on the argument usage. And the compiler is able to say, "looks like this anonymous type fits T, so lets make T the anonymous type." And thus, since MakeList returns List(Of T), x is a type of List(Of <Anonymous Type>). You can check it out yourself; intellisense works, and you can see the .Name and .Age fields when you do:

 Dim name = list(0).Name

And now we have a collection of anonymous types. You can use this technique to "name" anonymous types using type parameters in other scenarios as well.


Technorati tags: VisualBasic, AnonymousTypes tags: VisualBasic, AnonymousTypes