Anonymous types that look the same, are the same

Anonymous types are one of the features that was introduced as part of .net 3.5, they allow a programmer to make a new type dynamically, with its properties defined from its usage.

An quick example of an anonymous type might be:

var anon = new { AnInteger = 1, AString = "string" };
Console.WriteLine(anon.AString);

Behind the scenes, the compiler will create a class that looks somewhat like this:

class Anon
{
    public int AnInteger { get; private set; }
    public string AString { get; private set; }
}

The type doesn’t look exactly like that, but from a usage point of view, it’s close enough.

There is one important thing that you’ll need to know if you’re dealing with collections of anonymous types, is that if you have two collections of them, and you want to create a union of the two, then they have to be declared in the same way. If the properties name, type and order are exactly the same, the compiler will make them the same anonymous type, allowing them to be stored in the same strongly typed collection.

Given that, the follow example is valid code, and will create a strongly typed array of an anonymous type:

var anon1 = new { AnInteger = 1, AString = "string1" };
var anon2 = new { AnInteger = 2, AString = "string2" };

var unionedList = new[] { anon1, anon2 };

foreach (var item in unionedList)
    Console.WriteLine(item.AString);

As a contrast, here are some alternate definitions of ‘anon2’ that would generate compiler errors at line 4, where the array is created, because the compiler would make ‘anon2’ a different anonymous type:

// Would fail because AnInteger is of type 'string'
var anon2 = new { AnInteger = "2", AString = "string2" };

// Would fail because "AnInteger" is defined on anon1 and "AnIntegerX" is defined here
var anon2 = new { AnIntegerX = 2, AString = "string2" };

// Would fail because the order of the properties is different
var anon2 = new { AString = "string2", AnIntegerX = 2 };

Comments are closed.