Wednesday, February 3, 2010

Why this is not possible in C# Generics?


A colleague pointed me to a strange case in C# (not so sure if this actually strange though).
Suppose you have a class Employee. If you want to create a Generic List<> of type Employee, you can simply do:
List<Employee> x = new List<Employee>;
I understand that I need to pass the Employee type to the Generic list so that it knows the required type information about Employee and generates methods that return and accept parameters that are compatible with Employee. 
Now my question is, why isn't it possible to do the following?
Employee x = new Employee();
List<typeof(x)> list = new List<typeof(x)>();
Shouldn't this suffice the information required for List<> to know, in order to create a list? In other words, the type of x which is the type of Employee is now passed as a generic type parameter to List<>, which (as I used to believe) is the same as passing list the type name (in this case Employee). 
I wondered so, I posted a question on Stackoverflow.
If you're lazy enough to check the question, here's my selected answer, and boy it was submitted by Jon Skeet himself: 
typeof(x) doesn't work in C# either to get the type of a variable - it returns a Typereference for the type name, e.g. typeof(string) will return a reference to the Type object associated with the System.String type. That's equivalent to using String.class in Java. (Note that again, that's applying .class to a type name, not a variable name.)
Java generics don't support anything like your final statement either. If you believe they do, please give a sample :)
What you can do in C# is use type inference to do what you want:
public static List<T> CreateListForSampleType<T>(T sample)
{
    return new List<T>();
}
...
Employee x = new Employee();
var list = CreateListForSampleType(x);
Note that there's no reason why C# couldn't be extended to allow something liketypeof(variablename) or List - it's all compile-time type information, after all. However, I can't see that it would meet the team's requirements for usefulness... there are other far more useful features I'd like to see first :)