In the sample code shown below, the "CompileError" method won't compile, because it requires the where T : new()
constraint as shown in the CreateWithNew()
method. However, the CreateWithActivator<T>()
method compiles just fine without a constraint.
public class GenericTests
{
public T CompileError<T>() // compile error CS0304
{
return new T();
}
public T CreateWithNew<T>() where T : new() // builds ok
{
return new T();
}
public T CreateWithActivator<T>() // builds ok
{
return Activator.CreateInstance<T>();
}
}
Why is this?
According to https://mcmap.net/q/402609/-activator-createinstance-lt-t-gt-vs-new, which references MSDN documentation, and this question, the new T()
expression in generics is actually implemented using Activator.CreateInstance<T>()
. So I don't understand why calling new T()
requires that the generic type be constrained in a way that can be omitted when using Activator.CreateInstance<T>()
.
Or, to put the question the other way around: what's the point of the where T : new()
constraint, if it's easy to create instances of T
in a generic method without the constraint, by directly using the exact same underlying infrastructure?
CreateInstance()
just uses plain old reflection and isn't subject to any constraints. If the type has a default constructor, it will create it. – Avensdynamic
lets you write calls to functions that don't exist, so instead of a compiler error you get a runtime exception. Similarly, here,CreateInstance
lets you postpone finding out that no parameterless constructor exists until runtime. – Hand