Misc

Anonymous Types

Anonymous Types are another new feature to the C# 3.0 compiler.

To create one, just supply the new keyword without a class name, followed by the, also new, object initialiser notation.

As the type name is not known it needs to be assigned to a variable declared with the local variable type inference, var, keyword.

For example:

var anonType = new { FirstName = "Colin", MiddleName = "Angus", Surname = "Mackay" };

It is possible to assign a new object to the variable, but it must be created with the object initialisers in exactly the same order. If, say, the following is attempted a compiler error will be generated:

anonType = new {Surname = "Rowling",  FirstName = "Joanna", MiddleName = "Kathleen" };

The corresponding compiler error is: Cannot implicitly convert type ‘anonymous type […ProjectsConsoleApplication4ConsoleApplication4PropertiesAssemblyInfo.cs]’ to ‘anonymous type […ProjectsConsoleApplication4ConsoleApplication4PropertiesAssemblyInfo.cs]’

At the moment I’m not entirely sure where AssemblyInfo.cs comes in. If anyone knows the answer I’d love to know.

Back to the original example. What does this look like under the microscope of Lutz Roeder’s Reflector?

var <>g__initLocal0 = new <>f__AnonymousType0();
<>g__initLocal0.FirstName = "Colin";
<>g__initLocal0.MiddleName = "Angus";
<>g__initLocal0.Surname = "Mackay";
var anonType = <>g__initLocal0;

But that isn’t all that was generated. The compiler also generated the following internal class (Note: Some of the detail has been stripped for clarity)

internal sealed class <>f__AnonymousType0<<>j__AnonymousTypeTypeParameter1,
    <>j__AnonymousTypeTypeParameter2, <>j__AnonymousTypeTypeParameter3>
{
    // Fields
    private <>j__AnonymousTypeTypeParameter1 <>i__AnonymousTypeField4;
    private <>j__AnonymousTypeTypeParameter2 <>i__AnonymousTypeField5;
    private <>j__AnonymousTypeTypeParameter3 <>i__AnonymousTypeField6;

    public <>j__AnonymousTypeTypeParameter1 FirstName
    {
        get
        {
            return this.<>i__AnonymousTypeField4;
        }
        set
        {
            this.<>i__AnonymousTypeField4 = value;
        }
    }

    public <>j__AnonymousTypeTypeParameter2 MiddleName
    {
        get
        {
            return this.<>i__AnonymousTypeField5;
        }
        set
        {
            this.<>i__AnonymousTypeField5 = value;
        }
    }

    public <>j__AnonymousTypeTypeParameter3 Surname
    {
        get
        {
            return this.<>i__AnonymousTypeField6;
        }
        set
        {
            this.<>i__AnonymousTypeField6 = value;
        }
    }
}

Because the developer has no access to the actual type name the an object created as an anonymous type cannot be passed around the program unless it is cast to an object, the base class of all things. It cannot, for obvious reasons, be cast back again. So at this point the only way of accessing the data stored within is via reflection, or with methods already present on object.

Anonymous types can be examined in the debugger quite easily and show us just like any other object.

Debugging anonymous types in Orcas

One especially neat feature of anonymous types is its ability to infer a name when none is given. For example:

DateTime dateOfBirth = new DateTime(1759, 1, 25);
var anonType = new { FirstName = "Robert", Surname = "Burns", dateOfBirth };

The dateOfBirth entry was not explicitly given a name on the anonymous type. However, the compiler inferred a name based on the variable name that was given. The anonymous type therefore looks like this: { FirstName = Robert, Surname = Burns, dateOfBirth = 25/01/1759 00:00:00 }

Naturally, some will dislike this as the anonymous type now has a mix of pascal and camel case for the properties it is exposing.

NOTE: This post was rescued from the Google Cache. The orginal date was Saturday, 17th March, 2007

One thought on “Anonymous Types

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s