Anonymous types are a new thing to C# 3.5. An anonymous type is a class type that is used, but never formally defined.
In C# 2.0, if you needed a type that had 2 properties, you had to fully declare a class:
class Data
{
private int _id = 0;
public int Id
{
get { return _id; }
set { _id = value; }
}
private string _name = null;
public string Name
{
get { return _name; }
set { _name = value }
}
}
then in your function, you would use it:
Data d1 = new Data();
d1.Id = 5;
d1.Name = "Matt";
// ...
Console.WriteLine("{0} {1}", d1.Id, d1.Name);
C# 3.5 introduced a new type called an Anonymous Type. To do the above in C# 3.5, all you need is:
var d1 = new { Id = 5, Name = "Matt" };
// ...
Console.WriteLine("{0} {1}", d1.Id, d1.Name);
What exactly is an Anonymous Type?
An anonymous type is a limited scope data type that can be defined to have properties and then have those properties referenced.
The output from the above code would produce:
5 Matt
If we were to execute:
Console.WriteLine("{0}\n{1}", d1, d1.GetType());
we would get:
{ Id = 5, Name = Matt }
<>f__AnonymousType1`2[System.Int32,System.String]
So ToString() just mirrors our definition for the variable, and GetType() tells us that it's an anonymous type of type Int32 and type String.
So does it create a new anonymous type for each variable that's created? No. Actually, the compiler is pretty smart:
var d1 = new { Id = 5, Name = "Matt" };
var d2 = new { Id = 4, Name = "Mary" };
Console.WriteLine("{0}\n{1}", d1.GetType(),
d2.GetType());
produces
<>f__AnonymousType0`2[System.Int32,System.String]
<>f__AnonymousType0`2[System.Int32,System.String]
So it realized that the types were actually the same. In fact, it'll do the same thing if the anonymous type variables are defined in different functions.
However, what if we were to have the properties be of the same type but with different names?
var d1 = new { Id = 5, Name = "Matt" };
var d2 = new { Id2 = 4, Name = "Mary" };
Console.WriteLine("{0}\n{1}", d1.GetType(),
d2.GetType());
This gives a different result:
<>f__AnonymousType0`2[System.Int32,System.String]
<>f__AnonymousType2`2[System.Int32,System.String]
So it recognized that the types were very similar, but still different.
There are some restrictions on using anonymous types.
- You cannot use anonymous types as a parameter or the return value for a function.
- You can put anonymous types in a List<Object>, but it's type is lost.
- Any anonymous type variable is read-only.
Why would you use anonymous types? In reality, you probably won't. However, it is a tool added to C# in order to support another, much more useful, tool: LINQ. LINQ will be the subject of an upcoming post.