Microsoft & .NETVisual C#The New Anonymous Types Feature in C# 3.0

The New Anonymous Types Feature in C# 3.0

Developer.com content and product recommendations are editorially independent. We may make money when you click on links to our partners. Learn More.

At the PDC 2005, on the eve of the release of C# 2.0 (C# Whidbey), Microsoft previewed its plans for C# 3.0 (C# Orcas). Along with a list of fantastic new features such as Language Integrated Query (LINQ), Redmond also described a new feature called anonymous types. This article takes a deeper look at anonymous types.


Anonymous Types Defined


The C# 3.0 specifications describe anonymous types as tuple types automatically inferred and created from object initializers. Before you can fully understand the meaning of this definition, you need to understand the term “object initializer,” which is the basis of the anonymous types feature.


An object initializer specifies values from one or more fields or properties of an object. That means you specify a set of properties for an object through a series of assignments, such as {a = 10, b = 20}, and an object is assigned these properties. In other words, an anonymous type is one that previously did not exist and was not defined explicitly in code.


Note: The compiler creates the anonymous type at compile time and not run time.

You can see this class in the disassembly through ILDASM (the IL Disassembler):

var p1 = new {Name = “A”, Price = 3};

At compile time, the compiler creates a new (anonymous) type with properties inferred from the object initializer. Hence, the new type will have the properties Name and Price. The Get and Set methods, as well as the corresponding private variables to hold these properties, are generated automatically. At run time, an instance of this type is created and the properties of this instance are set to the values specified in the object initializer.


C# Internals


You might be surprised to learn that you define only the names of the properties and their values and C# 3.0 automatically creates a class from them. How does it do that? Check out how the compiler processes your request.


You started with the following line of code:

var p1 = new {Name = “A”, Price = 3};

When the C# 3.0 compiler encounters a request such as this, it converts it in the background into a more verbose declaration, such as this:

class __Anonymous1
{
private string name ;
private int price;
public string Name{ get { return name; } set { name = value ; } }
public int Price{ get { return price; } set { price= value ; } }
}
__Anonymous1 p1 = new __Anonymous1();
p1.Name = “A”;
pt.Price =3

Anonymous Types in Action


To get started, you need Visual Studio 2005 with .NET 2.0 installed. Next, you need to install the LINQ technology preview available for free download from MSDN.


If you have Visual Studio 2005 installed, you will have three new project templates titled LINQ Preview under Visual C#: LINQ Console Application, LINQ Windows Application, and LINQ Library.


To launch a project using anonymous types, take the following steps (Click here to download the accompanying source code for the example program.):



  1. Start the Visual Studio 2005 editor and create a new project, selecting LINQ Console as the project template in the New Project window.
  2. Name the project AnonTypes and click OK.
  3. Type the following code in the editor:
    // Program.cs
    using System;
    using System.Query;
    using System.Data.DLinq;
    namespace AnonTypes
    {
    class Program
    {
    static void Main(string[] args)
    {
    var p1 = new {Name = “A”, Price = 3};
    Console.WriteLine(“Name = {0}nPrice = {1}”,
    p1.Name, p1.Price);
    Console.ReadLine();
    }
    }
    }

  4. Compile the application, which should compile correctly.
  5. Execute the application. It should print out the following:
    Name = A
    Price = 3

If you don’t have Visual Studio 2005, you can still compile this application from the command line by typing the following:

C:Program FilesLINQ PreviewBinCsc.exe
/reference:”C:Program FilesLINQ PreviewBinSystem.Data.DLinq.dll”
/reference: System.dll
/reference:”C:Program FilesLINQ PreviewBinSystem.Query.dll”
/out:AnonTypes.exe /target:exe Program.cs

Even though you have not explicitly defined a class in the code, the C# compiler automatically performs the following tasks:



  1. Deciphers the type.
  2. Creates a new class (that has the property’s name and price).
  3. Uses this class to instantiate a new object.
  4. Assigns the object the parameters passed.

Delving Deep into the Code


To verify that the compiled assembly indeed creates a new class, start up ILDASM (located in C:Program FilesMicrosoft Visual Studio 8SDKv2.0Bin) and select the recently compiled assembly, AnonTypes.exe. Expand the tree-view, and you should see a view similar to Figure 1.

Figure 1. ILDASM Expanded Tree-view of AnonTypes


If you look carefully, ILDASM discloses information on how an anonymous type “<Projection>f__0” has been created. Along with the class, the private variables _Name (of the type string) and _Price (of the type ‘int’) have also been created. The Get and Set methods for both these variables also have been created, and they have the properties Name and Price.


Double-clicking any of the methods or variables reveals code that is very much like normal code. For example, when you click the Name property, you’ll see the following code:

.property instance string Name()
{
.get instance string AnonTypes.Program/
‘<Projection>f__0’::get_Name()
.set instance void AnonTypes.Program/
‘<Projection>f__0’::set_Name(string)
} // end of property ‘<Projection>f__0’::Name

Multiple Anonymous Types


If you have more than one anonymous type declared and their types are similar, the C# compiler is smart enough to detect that and produce only one class and create two instances of that class.


Suppose you have the following code (the newly added code is boldfaced):

using System;
using System.Query;
using System.Data.DLinq;
namespace AnonTypes
{
class Program
{
static void Main(string[] args)
{
var p1 = new {Name = “A”, Price = 3};
var p2 = new {Name = “A”, Price = 3};
Console.WriteLine(“Name = {0}nPrice = {1}”,
p1.Name, p1.Price);
Console.ReadLine();
}
}
}

When you compile this code and open the assembly with ILDASM, the structure will like Figure 2.

Figure 2. Multiple Anonymous Types with Similar Declarations


As you can see, because the declarations were similar, C# created only one anonymous class, thus optimizing the code. If the declarations were not similar, you would have two anonymous classes.


If you modify the above code to look like the following (the changed code is boldfaced):

new {Name = “A”, Price = 3};
var p2 = new {Name = “A”};

The C# compiler will create two different anonymous types because the types are different. Figure 3 shows the ILDASM representation.

Figure 3. Multiple Anonymous Types with Different Declarations


As you can see, C# has created two classes, <Projection>f__0 and <Projection>f__1.


Anonymous Types Without Explicit Class Structure Declaration


Anonymous types provide a mechanism for declaring anonymous types in your code without explicitly declaring the class structure. Additionally, the C# compiler is smart enough to optimize the creation of an anonymous type if one with a similar structure already exists.


Download the Code


To download the accompanying source code for the example program, click here.


About the Author


Vipul Patel is a Microsoft MVP (two years in a row) in Visual C#. He currently works at Microsoft through Volt Information Sciences, specializing in C# and deployment issues. Reach Vipul at Vipul_d_patel@hotmail.com.

Get the Free Newsletter!

Subscribe to Developer Insider for top news, trends & analysis

Latest Posts

Related Stories