Home All Groups Group Topic Archive Search About

Why does the generic constraint new() use Activator<T>.CreateInstance instead of new T()?

Author
5 Feb 2007 7:30 PM
mjduncan
Why does the generic constraint new() use Activator<T>.CreateInstance
instead of new T()?

An example

public class Foo<T>  : where T : class, new()
{
    T objectValue = new T();

    public foo() {}
}

If you look at Lutz's reflector you will get something like
T objectValue = Activator<T>.CreateInstance() in place of T
objectValue = new T();

Using the Activator class is obviously slower and unintuitive to me,
so why does the framework compile  my code using
Activator<T>.CreateInstance() instead of new T()?

Author
5 Feb 2007 9:22 PM
Mattias Sjögren
>Using the Activator class is obviously slower and unintuitive to me,
>so why does the framework compile  my code using
>Activator<T>.CreateInstance() instead of new T()?

new T usually compiles to the newobj IL instruction (when T is a
reference type). But newobj doesn't support generic type arguments.


Mattias

--
Mattias Sjögren [C# MVP]  mattias @ mvps.org
http://www.msjogren.net/dotnet/ | http://www.dotnetinterop.com
Please reply only to the newsgroup.
Author
6 Feb 2007 4:42 PM
Barry Kelly
Mattias Sjögren wrote:

> >Using the Activator class is obviously slower and unintuitive to me,
> >so why does the framework compile  my code using
> >Activator<T>.CreateInstance() instead of new T()?
>
> new T usually compiles to the newobj IL instruction (when T is a
> reference type). But newobj doesn't support generic type arguments.

Actually, the CLR does if you constrain the type argument to reference
types:

..method private hidebysig static void Foo<class .ctor T>() cil managed
// ...
  newobj instance void !!T::.ctor()

However, it will not pass PEVerify.

-- Barry

Author
5 Feb 2007 9:34 PM
Barry Kelly
mjdun***@gmail.com wrote:

Show quote
> Why does the generic constraint new() use Activator<T>.CreateInstance
> instead of new T()?
>
> An example
>
> public class Foo<T>  : where T : class, new()
> {
>     T objectValue = new T();
>
>     public foo() {}
> }
>
> If you look at Lutz's reflector you will get something like
> T objectValue = Activator<T>.CreateInstance() in place of T
> objectValue = new T();
>
> Using the Activator class is obviously slower and unintuitive to me,
> so why does the framework compile  my code using
> Activator<T>.CreateInstance() instead of new T()?

Probably because the compiler hasn't special-cased code generation based
on reference type constraint. It does special-case struct, in which case
it produces initobj rather than calling CreateInstance().

Because of the two different ways of initializing reference types and
value types (first by newobj with constructor argument, second by
initobj), in the most general case of a new() constraint something like
Activator<T>.CreateInstance() is needed.

-- Barry

Author
8 Feb 2007 3:47 PM
Laura T.
You can use newobj when you already know the type.
In the case of generics, you are creating a new type (closed type)  that
newobj cannot do.

<mjdun***@gmail.com> ha scritto nel messaggio
Show quote
news:1170703813.568619.137330@a34g2000cwb.googlegroups.com...
> Why does the generic constraint new() use Activator<T>.CreateInstance
> instead of new T()?
>
> An example
>
> public class Foo<T>  : where T : class, new()
> {
>    T objectValue = new T();
>
>    public foo() {}
> }
>
> If you look at Lutz's reflector you will get something like
> T objectValue = Activator<T>.CreateInstance() in place of T
> objectValue = new T();
>
> Using the Activator class is obviously slower and unintuitive to me,
> so why does the framework compile  my code using
> Activator<T>.CreateInstance() instead of new T()?
>

AddThis Social Bookmark Button