Here's some code I have written:
using System;
namespace GenericsTest
{
class Program
{
static void Main(string[] args)
{
Console.WriteLine(Create<MyClass>());
Console.Read();
}
static T Create<T>() where T : MyClass, new()
{
T t = new T();
t.Initialize();
return t;
}
}
class MyClass
{
public string str = " ";
public int i = 0;
public MyClass()
{
}
public void Initialize()
{
str = "test";
i = 1;
}
public override string ToString()
{
return base.ToString() + "\n" + str + "\n" + i;
}
}
}
My question is, is the above code faster or slower than the following code and by how much etc.:
static MyClass CreateMyClass()
{
MyClass cls = new MyClass();
cls.Initialize();
return cls;
}

1 answers
Create<T> is considerably slower than CreateMyClass().
This is because Create<T> doesn't know until runtime what T will be and therefore has to use reflection (it calls Activator.CreateInstance<T> under the hood) to instantiate T.
You'd need to do some time tests on your hardware, version of the CLR etc. but I think you'll find that its at least 5 times slower.
EDIT - see comments below
To quote from MSDN:
"The first time a generic type is constructed with any reference type, the runtime creates a specialized generic type with object references substituted for the parameters in the MSIL. Then, every time that a constructed type is instantiated with a reference type as its parameter, regardless of what type it is, the runtime reuses the previously created specialized version of the generic type. This is possible because all references are the same size."
So all generic types (or methods) which have type parameters which are reference types share the same native code implementation.
Suppose now the type or method contains code which instantiates the type represented by the type parameter using its parameterless constructor. As the type parameter could be any reference type which satisfies the constraints, it's not feasible for object creation code to be statically compiled into the native code because the runtime doesn't know what types may be used during the application's lifetime.
So, whenever the C# compiler comes across code such as this:
it replaces it (or its equivalent in MSIL) with:
The runtime then uses reflection to instantiate 't'.
Now, you can see from this description that what your teacher said about 'T' getting replaced with the actual class name at runtime and reflection not being required is more or less correct if we're only talking about the generic type or method being instantiated. But, if that type or method includes code to instantiate a reference type represented by a type parameter (as in your example), reflection is needed even though the type of the parameter may be known at compile time.
Altough this is much slower that a direct constructor call, it's not noticeable in practice unless thousands of objects are being constructed. Evidently, the .NET generics designers felt this was relatively unimportant compared to the major benefit of having a single native code implementation for all reference type parameters.
answered one year ago by:
17279
121
Oh? I was told opposite earlier today in fact almost exactly opposite. One of the teachers at my university mentioned that the 'T' gets replaced with the actual class name at runtime and reflection is not required. I ran a sloppy DateTime test and it seemed slower. So I'm thinking you're right.
17279
Ah, I can see now why you're confused about this. Please see my edit above for a full explanation.