Published on 02-06-2015

Working with Anonymous Types in LINQ

Anonymous types are convenient, as type names are automatically determined at compile time. However, they do have their limitations. This tutorial gives you an overview and practical examples of how to work with anonymous types in LINQ.

To begin this tutorial, let’s take a quick look at a basic example showing how an anonymous type is declared:

var myAnonymousType = new { Name = "Patty", Age = 25, IsMale = false };

The rules for declaring an anonymous type are few:

  1. the type cannot be expressed (hence, it is anonymous)
  2. there has to be a new keyword
  3. the property must have a name and value (for example Age = 25)
  4. it cannot be initialized with null

The reason it cannot be assigned null, is because there is no type which is bound no null.

The great thing about anonymous types used with LINQ is that you don’t have to think about casting the result type of your queries. This is especially useful when you work with types that have several properties. The compiler will replace the var keyword by a real type, which is always a reference type.

Let’s see this in action:

var people = new[] { 
            new { Name = "Patty", Age = 25, IsMale = false }, 
            new { Name = "Kenny", Age = 43, IsMale = true },
            new { Name = "Kate", Age = 37, IsMale = false } 
        };

var res = people.Where(p => p.Name.StartsWith("K")).Select(p => p);

foreach (var person in res)
    Console.WriteLine(person.Name);

// Outputs:
// Kenny
// Kate

The example takes all people from the array type starting with the letter “K” in their name, and prints them to the screen. Thus, both people and res are anonymous types.

Anonymous types are immutable, meaning they cannot be changed after they are created (which basically means they are read-only). Thus you cannot do this:

var people = new[] { 
        new { Name = "Patty", Age = 25, IsMale = false }, 
        new { Name = "Kenny", Age = 43, IsMale = true },
        new { Name = "Kate", Age = 37, IsMale = false } 
    };

var res = people.Where(p => p.Name.StartsWith("K")).Select(p => p);

res.First().Age = 27; // <- this won’t compile, as res is immutable!

However, it will be perfectly fine to use res to expand the existing query, because we are then working on the same anonymous types, which the compiler already will recognize:

var people = new[] { 
            new { Name = "Patty", Age = 25, IsMale = false }, 
            new { Name = "Kenny", Age = 43, IsMale = true },
            new { Name = "Kate", Age = 37, IsMale = false } 
        }

var res = people.Where(p => p.Name.StartsWith("K")).Select(p => p);

res = people.Where(p => p.Age >= 40).Select(p => p); // < ok

foreach (var person in res)
    console.writeline(person.name);

This limitation of anonymous types being immutable would not normally be a problem, but should you ever need to change the values inside of an anonymous type you can pass data to a named class and then alter data.

Since an anonymous type is derived directly from System.Object, it always implements the methods Equals(), GetHashCode(), and ToString(). It is worth mentioning, that Equals() and GetHashcode() consider two instances of anonymous types as equal, when all their properties are equal. You can see the official explanation of this in the C# Language Specification here.

An anonymous type cannot be easily returned from a method as it has what is called method scope. One way to get around this problem is to convert the anonymous type to an object before it is returned.

As you have seen in this short tutorial, anonymous types can make life a lot more convenient to the .NET developer who use LINQ. I hope you now have a better view of its advantages and limitations.