Keyed Anonymous Types in VB9


Anonymous types use the Dim keyword but do not include a formal type—that you code—in the initialization statement. That is, the New keyword is used but there's no class name. These are not invariant types; these are strong types but the class is code-generated by the compiler and emitted to MSIL (the binary assembly) as an anonymous type.

Anonymous types are emitted using the same definition if the field names, number, and order are identical. Anonymous types are generated using generics so the field types can differ and still the same anonymous types will be used. If there are differences in the right-hand-side definition—for example, you use more or fewer fields, change the name—called the member declaratory—or add special qualifiers such as a key, the anonymous types will vary.

Visual Basic anonymous types are mutable—the field values can be changed—which is the opposite of C# anonymous types. C# anonymous types are immutable. However, you can use the Key keyword to designate certain fields in VB9 as fixed (or immutable), and that's what this article is about.

Defining Keyed Anonymous Types

Keyed anonymous types are very similar in the declaration style as un-keyed anonymous types. In the former, you are simply introducing the new Key keyword for each field you'd like keyed. Here are two examples; the first shows an anonymous type and the second shows the same type keyed.

Dim person = New With {.ID = 1, .Name = "Paul Kimmel", _
                       .Title = "Keyed Anonymous Types"}

Now here is a similar anonymous type, including a key:

Dim person = New With {Key .ID = 1, .Name = "Paul Kimmel", _
                           .Title = "Keyed Anonymous Types"}

In the second example, you are indicating that ID is a keyed field. The first difference is that ID, Name, and Title can all be assigned to in the first definition, but in the second ID is read-only. (If you look at the MSIL, you will see that the second anonymous type defines ID as private initonly, or read only, and that while Name and Title has getters and setters ID has a getter only. You can look at the MSIL with ILDASM or use a decompiler and disassembler like Reflector.)

Quite simply, all fields in anonymous types can appear on the left hand side of the assignment operator (=) unless that field was qualified with the Key keyword.

Understanding How Keys Are Treated

Remember, everything in .NET inherits from the Object class. Anonymous types inherit directly from Object; this means they get Equals, GetHashCode, ToString, and GetType methods. If an anonymous typed introduces a key, Equals and GetHashCode are overridden. Keyed anonymous types with the same code-generated class and same key are considered identical because keyed anonymous types use the key to determine hash-equality. Listing 1 contains some sample code you can play with to explore how anonymous types with and without keys behave. You are encouraged to look at the ILDASM to see how the compiler treats each variation.

Listing 1: Sample code for exploring keyed anonymous type relationships.

Module Module1

   Sub Main()
      Dim NoKey = New With {.ID = 1, .Name = "Paul Kimmel", _
         .Article = "Keyed AnonymousTypes in VB9"}
      Dim NoKey2 = New With {.ID = "PAULKI01", .Name = "Paul Kimmel", _
         .Article = "Keyed AnonymousTypes in VB9"}
      ' False
      Dim HasKey = New With {Key .ID = 1, .Name = "Paul Kimmel", _
         .Article = "Keyed AnonymousTypes in VB9"}
      ' ID, Name, Article are member declarators
      'HasKey.ID = 2                    ' error - ID is read only
      HasKey.Name = "Paul T. Kimmel"    ' ok - Name and Article
                                        ' can change
      Dim HasKey2 = New With {Key .ID = 1, .Name = "Joe Swanson", _
         .Article = "Keyed AnonymousTypes in VB9"}
      Console.WriteLine("Has Key hash: " + _
      Console.WriteLine("Has Key (2) hash: " + _
   End Sub
End Module


In summary, if two anonymous types in the same assembly (project, .DLL, or .EXE) have the same member declarator (or field) names, inferred types, the same field order, and the same key value, the equality test will return true. Different anonymous types with a key can be tested for equality but will be unequal, and the same anonymous types with no key will be unequal.

About the Author

Paul Kimmel is the VB Today columnist for and has written several books on object-oriented programming and .NET. Check out his new book UML DeMystified from McGraw-Hill/Osborne. Paul is a software architect for Tri-State Hospital Supply Corporation. You may contact him for technology questions at

If you are interested in joining or sponsoring a .NET Users Group, check out Glugnet has opened a users group branch in Flint, Michigan that began in August 2007. If you are interested in attending, check out the web site for updates.

Copyright © 2007 by Paul T. Kimmel. All Rights Reserved.


  • There are no comments yet. Be the first to comment!

Leave a Comment
  • Your email address will not be published. All fields are required.

Top White Papers and Webcasts

  • Learn How A Global Entertainment Company Saw a 448% ROI Every business today uses software to manage systems, deliver products, and empower employees to do their jobs. But software inevitably breaks, and when it does, businesses lose money -- in the form of dissatisfied customers, missed SLAs or lost productivity. PagerDuty, an operations performance platform, solves this problem by helping operations engineers and developers more effectively manage and resolve incidents across a company's global operations. …

  • The hard facts on SaaS adoption in over 80,000 enterprises: Public vs. private companies Mid-market vs. large enterprise GoogleApps, Office365, Salesforce & more Why security is a growing concern Fill out the form to download the full cloud adoption report.

Most Popular Programming Stories

More for Developers

RSS Feeds