BlackWaspTM

This web site uses cookies. By using the site you accept the cookie policy.This message is for compliance with the UK ICO law.

C# Programming
.NET 3.0+

C# Anonymous Types

A new feature of C# 3.0 is the ability to create anonymous types. These interesting classes are defined for temporary use within class members. They allow the convenient encapsulation of read-only properties without the need to code a complete class.

What is an Anonymous Type?

Usually well-defined classes encapsulate the behaviour and state of a type of object, hiding the implementation details from the class's consumers. However, sometimes a lightweight class will be defined that contains only properties and that is for use in only a small section of code. Creating a new definition for such a class can be time-consuming when considered against the benefits obtained.

C# anonymous types allow lightweight classes containing read-only properties to be quickly declared and assigned using a convenient syntax. These types only permit the collecting together of related data items. They do not permit any additional functionality to be added in the form of methods or other class members.

Creating Anonymous Types

Anonymous types are created using the "var" keyword and a syntax similar to that of implicitly typed variables. Instead of assigning a simple value to the new variable, the object is created using the "new" keyword but with no named type. The "new" keyword is simply followed by a list of properties, each named and assigned a value, within a pair of brace characters {}. The general syntax is as follows:

var varname = new { Prop-Name-1 = prop-value-1, ..., Prop-Name-X = prop-value-X };

To create an anonymously typed object in this manner, each property must be named and a value assigned. The individual properties are implicitly typed according to the value provided.

To demonstrate this new syntax, try the following sample. This creates a new object based upon an anonymous type that represents a car. The properties of the object are then outputted to the console. NB: If you type the code manually using Visual Studio 2008 you will notice that the class is fully supported by Intellisense.

var dino = new
{
    Make = "Ferrari",
    Model = "Dino",
    Colour = "Red"
};

Console.WriteLine(dino.Make);       // Outputs "Ferrari"
Console.WriteLine(dino.Model);      // Outputs "Dino"
Console.WriteLine(dino.Colour);     // Outputs "Red"

The Object Base Class

Anonymous types are always generated as classes that have a base class of Object. As such, they inherit the members of Object. Four interesting inherited methods are Equals, GetHashCode, GetType and ToString.

Equals Method

Two anonymously typed objects can be compared for a match using either the equality operator (==) or the Equals method. The equality operator is not overloaded so compares the two references, as with comparing objects. If the two references are pointing to the same underlying object data, the result of the operation is true. If the references are different the operation returns false, even if the properties of the two objects match.

The Equals method is overloaded in the anonymous type to provide different functionality to the base class version. When two anonymously typed objects are compared using the method, each property is compared individually. If every property is an exact match, the result is true. This allows anonymous types, which are reference types, to behave similarly to value types.

NB: If the anonymous types have different signatures, the == operator may not be used and the Equals method will return false. The types are considered different if the named properties are not an exact match, even if the same names are used in a different order. This can be seen in the following code sample:

var cat1 = new { Name = "Mog", Age = 5 };
var cat2 = new { Name = "Tabby", Age = 5 };
var cat3 = new { Name = "Tabby", Age = 5 };
var cat4 = new { Age = 5, Name = "Mew" };

bool result;

result = cat1 == cat2;              // result = false
result = cat3 == cat4;              // Does not compile
result = cat1.Equals(cat2);         // result = false
result = cat2.Equals(cat3);         // result = true
result = cat3.Equals(cat4);         // result = false

GetHashCode Method

The GetHashCode method is overridden by anonymous types to provide compatibility with the Equals method. When the hash code is computed, the value of every property in the object is included in the calculation.

var cat1 = new { Name = "Mog", Age = 5 };
var cat2 = new { Name = "Tabby", Age = 5 };
var cat3 = new { Name = "Tabby", Age = 5 };

Console.WriteLine("cat1 / {0}", cat1.GetHashCode());
Console.WriteLine("cat2 / {0}", cat2.GetHashCode());
Console.WriteLine("cat3 / {0}", cat3.GetHashCode());

/* OUTPUT

cat1 / -1957230611
cat2 / -2011558908
cat3 / -2011558908

*/
4 June 2008