As an OO programmer, you know the benefits of defining classes to represent the state and functionality of a given programming entity. To be sure, whenever you need to define a class that is intended to be reused across projects and provides numerous bits of functionality through a set of methods, events, properties, and custom constructors, creating a new VB class is common practice and often mandatory.
However, there are other times in programming when you would like to define a class simply to model a set of encapsulated (and somehow related) data points without any associated methods, events, or other custom functionality. Furthermore, what if this type is only used internally to your current application and it?s not intended to be reused? If you need such a ?temporary? type, earlier versions of VB would require you to nevertheless build a new class definition by hand:
1: Class SomeClass
2: ' Define a set of private member variables...
3:
4: ' Make a property for each member variable...
5:
6: ' Override ToString() to account for each member variable...
7:
8: ' Override GetHashCode() and Equals() to work with value-based equality...
9: End Class
While building such a class is not rocket science, it can be rather labor intensive if you are attempting to encapsulate more than a handful of members. As of VB 2008, we are now provided with a massive shortcut for this very situation termed anonymous types. Consider the following VB sub:
1: Sub Main()
2: Console.WriteLine("***** Fun with Anonymous Types *****")
3:
4: ' Make an anonymous type representing a car.
5: Dim myCar = New With { .Color = "Bright Pink", _
6: .Make = "Saab", .CurrentSpeed = 55 }
7:
8: ' Now show the color and make.
9: Console.WriteLine("My car is a {0} {1}.", myCar.Color, myCar.Make)
10: Console.ReadLine()
11: End Sub
Again note that the myCar variable must be implicitly typed, which makes good sense, as we are not modeling the concept of an automobile using a strongly typed class definition. At compile time, the VB compiler will autogenerate a uniquely named class on our behalf. Given the fact that this class name is not directly visible from our VB code base, the use of implicit typing is in this case mandatory.
Also notice that we have to specify (using object initialization syntax) the set of properties that model the data we are attempting to encapsulate. Once defined, these values can then be obtained using standard VB property invocation syntax.
All anonymous types are automatically derived from System.Object, and therefore support each of the members provided by this base class on the implicitly typed myCar object. Assume your initial module defines the following new method:
1: Sub ReflectOverAnonymousType(ByVal obj As Object)
2: Console.WriteLine("obj is an instance of: {0}", obj.GetType().Name)
3: Console.WriteLine("Base class of {0} is {1}", _
4: obj.GetType().Name, _
5: obj.GetType().BaseType)
6: Console.WriteLine("obj.ToString() = {0}", obj.ToString())
7: Console.WriteLine("obj.GetHashCode() = {0}", obj.GetHashCode())
8: Console.WriteLine()
9: End Sub
Now assume we invoke this method from Main(), passing in the myCar object as the parameter:
1: Sub Main()
2: Console.WriteLine("***** Fun with Anonymous Types *****")
3:
4: ' Make an anonymous type representing a car.
5: Dim myCar = New With {.Color = "Bright Pink", .Make = "Saab", .CurrentSpeed = 55}
6:
7: ' Now show the color and make.
8: Console.WriteLine("My car is a {0} {1}.", myCar.Color, myCar.Make)
9:
10: ' Reflect over what the compiler generated.
11: ReflectOverAnonymousType(myCar)
12: Console.ReadLine()
13: End Sub
Check out the output shown here:

First of all, notice that in this example, the myCar object is of type VB$AnonymousType_0`3 (your name may differ). Remember that the assigned type name is completely determined by the compiler and is not directly accessible in your VB code base.
Perhaps most important, notice that each name/value pair defined using the object initialization syntax is mapped to an identically named property (which can be verified using tools such as reflector.exe or ildasm.exe). Because a VB anonymous type yields read/write properties for each item defined within the initialization list, you are free to change the state of your object after creation using standard property syntax:
1: ' Make an anonymous type representing a car.
2: Dim myCar = New With {.Color = "Bright Pink", .Make = "Saab", .CurrentSpeed = 55}
3:
4: ' Now change the color.
5: myCar.Color = "Black"
It is possible to create an anonymous type that is composed of additional anonymous types. For example, assume you wish to model a purchase order that consists of a timestamp, a price point, and the automobile purchased. Here is a new (slightly more sophisticated) anonymous type representing such an entity:
1: Sub CompositeAnonymousType()
2: ' Make an anonymous type that is composed of another.
3: Dim purchaseItem = New With { _
4: .TimeBought = DateTime.Now, _
5: .ItemBought = New With {.Color = "Red", .Make = "Saab", .CurrentSpeed = 55}, _
6: .Price = 34.0}
7: ReflectOverAnonymousType(purchaseItem)
8: End Sub
At this point, you should understand the syntax used to define anonymous types, but you may still be wondering exactly where (and when) to make use of this new language feature. To be blunt, anonymous type declarations should be used sparingly, typically only when making use of the LINQ technology set. You would never want to abandon the use of strongly typed classes/structures simply for the sake of doing so, given anonymous types? numerous limitations, which include the following:
- You don?t control the name of the anonymous type.
- Anonymous types always extend System.Object.
- Anonymous types cannot support events, custom methods, custom operators, or custom overrides.
- Anonymous types are always implicitly sealed.
- Anonymous types are always created using the default constructor.
However, when programming with the LINQ technology set, you will find that in many cases this syntax can be very helpful when you wish to quickly model the overall shape of an entity rather than its functionality.