In C# it is possible to create a class instance by using compiler-generated types. This concept was introduced with .NET 3 and is called: anonymous types. If you use such an anonymous type, the compiler will automatically create a type with the given properties. The following source code shows an according example.
static void Main(string[] args) { var person = new { FirstName = "John", LastName = "Doe" }; Console.WriteLine(person.GetType()); Console.WriteLine(person.FirstName + " " + person.LastName); Console.ReadKey(); }
The application creates the following output:
<>f__AnonymousType0’2[System.String,System.String]
John Doe
As you can see, a person instance was created without defining a specific type for a person. The compiler will create this type based on the given properties. The created properties are read only. The type name is generated by the compiler and is not available at the source code level. But the properties and methods of the type are available in IntelliSense.
Types of anonymous objects
If you create several anonymous types with the same parameters, then the created types are equal. “Same parameters” mean, they have to be the same names, the same number, the same parameter types and the some order. The following example shows an according example with three person instances. Person 1 and 2 should have the same type because the parameters are the same, but person 3 should have a different type, because the order of the parameters is changed.
static void Main(string[] args) { var person1 = new { FirstName = "John", LastName = "Doe" }; var person2 = new { FirstName = "Jane", LastName = "Doe" }; var person3 = new { LastName = "Smith", FirstName = "John" }; Console.WriteLine(person1.GetType()); Console.WriteLine(person2.GetType()); Console.WriteLine(person3.GetType()); Console.ReadKey(); }
The application creates the following output. The result is like expected. The compiler has created two different types.
<>f__AnonymousType0’2[System.String,System.String]
<>f__AnonymousType0’2[System.String,System.String]
<>f__AnonymousType1’2[System.String,System.String]
Methods
Additional to the read only properties, the anonymous type always contains the methods ToString(), Equals() and GetHashCode(). So these types may correctly perform property comparisons and hashing.
static void Main(string[] args) { var person1 = new { FirstName = "John", LastName = "Doe" }; var person2 = new { FirstName = "Jane", LastName = "Doe" }; Console.WriteLine("ToString: " + person1.ToString()); Console.WriteLine("GetHashCode: " + person1.GetHashCode()); Console.WriteLine("Equals: " + person1.Equals(person2)); Console.ReadKey(); }
The application creates the following output within the console:
ToString: { FirstName = John, LastName = Doe}
GetHashCode: 1115579845
Equals: False
Use anonymous types outside of a method
The type name of a anonymous type is generated by the compiler and is not available at the source code level. Therefore it is not possible to explicitly use an anonymous type as method parameter or return value. Of course these types are based on object and therefore you may use object as return type of a method but if you want to use the anonymous type outside of the method you have to cast it back to the origin type which you don’t know.
With C# 4 a new keyword was introduced: dynamic. You may use dynamic if you want to use an anonymous type as return value of a method. In this case you can use the type and access the type properties outside of the method. But dynamic has the disadvantage that IntelliSense cannot show you the type properties and methods.
The following source code shows an example method with an dynamic type as return value.
static void Main(string[] args) { var person1 = MyMethod(); var person2 = new { FirstName = "Jane", LastName = "Doe" }; Console.WriteLine(person1.GetType()); Console.WriteLine(person2.GetType()); Console.WriteLine(person1.FirstName + " " + person1.LastName); Console.ReadKey(); } static dynamic MyMethod() { var person = new { FirstName = "John", LastName = "Doe" }; Console.WriteLine(person.GetType()); return person; }
The application creates the following output within the console:
<>f__AnonymousType0’2[System.String,System.String]
<>f__AnonymousType0’2[System.String,System.String]
<>f__AnonymousType0’2[System.String,System.String]
John Doe
Summary
Anonymous types are automatically created by the compiler based on the number, type, names, and order of the given properties. The compiler will create a type with read-only properties and adds the methods Equals() and GetHashCode()which makes anonymous types ideal for LINQ expressions.
Anonymous types are a good choice if you have to create temporary data objects in a small scope, e.g. within a method. But if you want to use a type in different methods I recommend to use an explicitly implemented type, because with anonymous types such use cases will very often result in dirty source code.