This is the my fifth post in the series of posts I am making on the new features in C#3.0. See the previous posts on var, extension method, lambda expressions and object-collection initializers
Before getting into why I do not like (actually hate) anonymous types in C#. Let's see what is this anonymous types and whats so special with this anonymity.
Anonymous types
Anonymous type is syntactic sugar to reduce typing. Let's say I need to create a structure or class to contain some data regarding customers. This is how you do it in C# 1.0
class Customer{ private string name; public string Name { get { return name; } set { name = value; }} private string address; public string Address { get { return address; } set { address = value; } }} Customer cust = new Customer();cust.Name = "Abhinaba Basu";cust.Address = "Hyderabad, India";
class
{
public string Name { get { return name; } set { name = value; }}
private string address;
public string Address { get { return address; } set { address = value; } }
}
Customer cust = new Customer();
cust.Name = "Abhinaba Basu";
cust.Address = "Hyderabad, India";
Or using the new Object initialization syntax of C#3.0 as
var cust = new Customer{Name = "Abhinaba Basu", Address = "Hyderabad, India"};
var cust =
This is a very repitative code pattern of creating data only containers (class or struct) for the related data types. This is can be done with the Anonymous method syntax as
var cust1 = new { Name = "Abhinaba Basu", Address = "Hyderabad, India" };
var cust1 =
Note that in this statement I have not named a type and hence the compiler emits code to generate a new class definition whose name is not know to us and hence is a Anonymous type. The following code is generated.
public sealed class <Projection>f__0{ // Methods public <Projection>f__0(); public override bool Equals(object); public override int GetHashCode(); public override string ToString(); // Properties public string Address { get; set; } public string Name { get; set; } // Fields private string _Address; private string _Name;}
public
Here <Projection>f__0 is the generated class' name. For each member a private field and the corresponding property is generated. The class also generates proper implementation to override Equals, GetHashCode and ToString methods based on each of the fields. The rest of the code is same as that used for Object initialization.
If we have two such declaration that match in the field types then the same class will be used for both of them.
var cust1 = new { Name = "Abhinaba", Address = "Hyderabad" };var cust2 = new { Name = "Ankur", Address = "Noida"};if (cust1.GetType() == cust2.GetType()) Console.WriteLine("Cust1 and Cust2 are of the same type {0}", cust2.GetType().ToString());// output:// Cust1 and Cust2 are of the same type // AnonymousTypes.Program+<Projection>f__0
var cust2 =
cust2.GetType().ToString());// output:
// Cust1 and Cust2 are of the same type // AnonymousTypes.Program+<Projection>f__0
There are couple of interesting point here
You can also use nested declaration as in
var cust = new { Name = "Abhinaba Basu", Address = "Hyderabad, India", Phone = new { AreaCode = 33, Number = 444444}};
Phone =
Why I do not like anonymous types
Again due to my upbringing in C/C++ I did not like implicit types when I saw it. This is taking the same idea to an extreme. Now not only are we letting the compiler choose the type for me I am also letting it generate new types!!!
Even without my pre-disposition I think that this construct address some special programming cases and should not have been included in the language. It'll just add to the surface area and learning curve and mainly go unused. The unusability comes from the following reasons