Click here to Skip to main content
Click here to Skip to main content

Internals of Anonymous Types

By , 16 Mar 2011
Rate this:
Please Sign up or sign in to vote.

.NET comes with lots of new features as it introduces new features. Many of them are quite useful while others might be very specific to an issue. One of the features that came up recently with the introduction of .NET 3.5 in C# is anonymous method. Anonymous means an object with no name. Before .NET 3.5, we had concept of anonymous delegates in C#. If you read about internals of delegate, you must already know how anonymous delegates are declared to CLR. In fact, there is no concept of anonymous in MSIL. Hence everything that you see as anonymous is actually a level of abstraction to us, and lets us to avoid the complexity to maintain unnecessary types to our program. In this post, I will discuss about anonymous type in terms of MSIL.

The Basics

Anonymous types are those types which are not declared before they are used. Say while you are doing your program, you want a temporary storage of your data, what you need to do, you need either declare a concrete class for the storage of the same, or you can use any collection like ArrayList, HashTable, etc. to store the key value collection. C# 3.5 and onwards allows you to dynamically create a type and use it directly in your program. You can use ‘var’ or implicit type declaration to ensure you could use the properties just like normal types.

var myruntimeObject = new { FirstProperty = 10, SecondProperty = new DateTime(), 
			ThirdProperty = "string type" };

Console.WriteLine("Type of myruntimeObject is {0}", myruntimeObject.GetType().Name);
Console.WriteLine("Type of FirstProperty is {0}",       
	myruntimeObject.FirstProperty.GetType().Name);
Console.WriteLine("Type of SecondProperty is {0}", 
	myruntimeObject.SecondProperty.GetType().Name);
Console.WriteLine("Type of ThirdProperty is {0}",
	myruntimeObject.ThirdProperty.GetType().Name);

Console.Read();

In the above example, I have created one anonymous type using var. The var will give you a chance to get intellesense in your code. You can see the variable holds an object of an anonymous type generated runtime. The power of var in code can also be tested. Just hover over the var keyword and you will see that the type is defined as anonymous.

In the previous code after the declaration of anonymous object, I have tried to see what exactly the type of the object and the members look like that I have declared. Let's see the output below:

So the actual type created by CLR at runtime looks like <>f_AnnonymousType0`3. We will discuss about it later in this post, but the thing that you might wonder, is the compiler is smart enough to declare the type of the members exactly. The FirstProperty is declared as Int32, second as DateTime and third as String. The type is self evaluated in the code and declared accordingly.

Now if I change the value just a bit like:

var myruntimeObject = new 
{ 
   FirstProperty = 10d, 
   SecondProperty = new DateTime(), 
   ThirdProperty = "string type" 
};

The code says the FirstProperty is double. The 10d is evaluated as double value.

You are also free to declare anonymous type for its members.

var myruntimeObject = new { FirstProperty = 10, 
	SecondProperty = new DateTime(), ThirdProperty = "string type", 
	MoreProperty = new { N1 = "" } };

Here the MoreProperty declares another anonymous type implicitly. But there is restriction in the usage of anonymous types. You cannot declare a method inside any object declaration, even there is no way to give accessibility specifier to its members. All the members inside an anonymous type are readonly properties, hence if you try to do:

myruntimeObject.FirstProperty = 20;

It will prompt you an error.

Another important thing about anonymous type is that the compiler is smart enough to use anonymous type gracefully. It does not create a new anonymous type if the next instruction exactly tries to create the same class. Hence if you use:

var myruntimeObject = new { FirstProperty = 10, SecondProperty = new DateTime(), 
	ThirdProperty = "string type", MoreProperty = new { N1 = "" } };

var myruntimeObject2 = new { FirstProperty = 30, SecondProperty = new DateTime(), 
	ThirdProperty = "string type2", MoreProperty = new { N1 = "blah blah" } };

Both internally represent the same type.

The Internals

Now as you know the basics of anonymous Types, let's look deep into its internal structure. In terms of IL, both var and anonymous type is nothing. Var is actually represented as actual type while anonymous type is mapped to an actual type.

The object creation looks similar to:

<>f__AnonymousType0<<N1>j__TPar> moreproperty = new <>f__AnonymousType0<<N1>j__TPar>("");

<>f__AnonymousType1<<FirstProperty>j__TPar, 
	<SecondProperty>j__TPar, <ThirdProperty>j__TPar, <MoreProperty>j__TPar> 
                myruntimeObject = new 
                <>f__AnonymousType1<<FirstProperty>j__TPar, 
		<SecondProperty>j__TPar, <ThirdProperty>j__TPar, 
		<MoreProperty>j__TPar>(10, new DateTime(), "string type", moreproperty);

Hence, it seems to be quite a big name for the type and also includes a generic argument named <N1>j__TPar. This lets the object to refer to the same type when argument differs. As Reflection API is not good enough to show the actual generic types, it shows a numeric representation for the same.

Now as you can see, the Compiler generated type for MoreProperty looks like the one above. The first thing that you should notice is the DebuggerDisplayAttribute just above class. With this attribute, Visual Studio debugger shows only <anonymous type> rather than the whole type name.

The Type takes a Generic type argument <N1>j__TPar in its constructor and builds the class. You should notice the parameter is marked as Readonly, so it is not writable. Also the type overrides ToString, GetHashCode and Equals by using the generic EqualityComparer. This looks like a nice implementation.

Conclusion

Finally, to conclude, I must say anonymous types is an interesting feature which is widely used and eventually changed the way of coding. It is very much useful while working with LINQ. We will discuss internals of LINQ in a later part of the series. But there should be a provision to define methods inside an anonymous type, which I think will be added sooner than later.

I hope you like my post. Give your feedback.
Happy coding.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)

About the Author

Abhishek Sur
Architect
India India
Did you like his post?
 
Oh, lets go a bit further to know him better.
Visit his Website : www.abhisheksur.com to know more about Abhishek.
 
Abhishek also authored a book on .NET 4.5 Features and recommends you to read it, you will learn a lot from it.
http://bit.ly/EXPERTCookBook
 
Basically he is from India, who loves to explore the .NET world. He loves to code and in his leisure you always find him talking about technical stuffs.
 
Presently he is working in WPF, a new foundation to UI development, but mostly he likes to work on architecture and business classes. ASP.NET is one of his strength as well.
Have any problem? Write to him in his Forum.
 
You can also mail him directly to abhi2434@yahoo.com
 
Want a Coder like him for your project?
Drop him a mail to contact@abhisheksur.com
 
Visit His Blog

Dotnet Tricks and Tips



Dont forget to vote or share your comments about his Writing
Follow on   Twitter   Google+

Comments and Discussions

 
GeneralMy vote of 5 PinmvpAbhijit Jana8-Mar-11 21:11 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.

| Advertise | Privacy | Mobile
Web04 | 2.8.140421.2 | Last Updated 16 Mar 2011
Article Copyright 2011 by Abhishek Sur
Everything else Copyright © CodeProject, 1999-2014
Terms of Use
Layout: fixed | fluid