In the previous post, we discussed using the var keyword. One of the primary use cases of the var keyword is anonymous types. In this post, we are going to look closer into anonymous types.
Anonymous types
An anonymous type is a nameless class that inherits from an object.
The type is inferred, by the compiler, at initialization.
For example, a typical anonymous declaration would look like this:
var person = new { FirstName = "John", LastName = "Power", Age = 33 };
We can see, just like any other object, it supports IntelliSense. We can see all the properties we defined and the methods coming from the Object class, such as ToString() and Equals(). So it is a strongly-typed class. We don’t know the type.

The properties are read-only. If we try to assign another value, we get the following error:
Compilation error (line 11, col 3): Property or indexer 'AnonymousType#1.Age' cannot be assigned to -- it is read only

Since we don’t have a handle on the class, how can we create another object of this type? The answer is simple: We make another anonymous type with the same properties.
For example, the following example would compile successfully:
public class Program { public static void Main() { var firstPerson = new { FirstName = "John", LastName = "Power", Age = 33 }; var secondPerson = new { FirstName = "Jane", LastName = "Power", Age = 44 }; firstPerson = secondPerson; } }
secondPerson can be assigned to firstPerson as they have the same type. An assignment is only possible if all the properties match. If we remove the Age property from the secondPerson, we get the error shown below:
Compilation error (line 18, col 17): Cannot implicitly convert type 'AnonymousType#1' to 'AnonymousType#2'
Shorthand Declarations
We don’t need to specify the property names if we assign the object from another. So, for example, if we wanted to create a second object of the same type with the same values, we could use this syntax:

As shown in the screenshot above, we can still see the same property names as the firstPerson object.
Internals of Anonymous Types
So what happens when we compile our application with anonymous types? The type names are generated automatically by the compiler.
The example below shows what our class looks like with an IL viewer:

We declared the firstPerson and secondPerson objects defined (of the same type) as:
instance void class '<>f__AnonymousType0`3'<string, string, int32>::.ctor(!0/*string*/, !1/*string*/, !2/*int32*/)
These auto-generated type names are hidden from the developer because we don’t need to know what they are. So it’s generally a bad practice to find out these types via reflection.
The final example shows the IL output when I’ve removed the Age property from the secondPerson object. Now that the properties don’t match with firstPerson, the compiler generates a new type for secondPerson named <> f__AnonymousType1’2:
