tags:

views:

75

answers:

2

The type argument must have a public parameterless constructor. When used together with other constraints, the new() constraint must be specified last.

Can you guys give me a sample scenario when this constraint is needed?

+6  A: 

This is essentially what the new() constraint boils down to:

class Factory<T> where T : new()
{
    public T Create()
    {
        return new T();
        //     ^^^^^^^
        //     this requires the new() type constraint.
    }
}

Now, you're not allowed to pass arguments to the constructor. If you nevertheless want to initialize the newed object, you could achieve this e.g. by introducing a further constraint:

interface ILikeBananas
{
    double GreenBananaPreferenceFactor { get; set; }
}

class Factory<T> where T : ILikeBananas, new()
{
    public T Create(double greenBananaPreferenceFactor)
    {
        ILikeBananas result = new T();
        result.GreenBananaPreferenceFactor = greenBananaPreferenceFactor;

        return (T)result;
        //     ^^^^^^^^^
        //     freely converting between ILikeBananas and T is permitted
        //     only because of the interface constraint.
    }
}

Note that another way of instantiating an object is via Activator.CreateInstance, which gives you some more freedom, such as passing arguments directly to a constructor.

Activator.CreateInstance does not strictly require the new() constraint; however, the type being instantiated still needs to provide a suitable constructor.

stakx
While this is a good answer, I personally kind of hate when somebody writes a `Factory<T>` with a `where T : new()` constraint while at the same time saying, "all `T` objects must be instantiated using this factory!" Like, if you really want to restrict instantiation to your factory, don't *require* that it be instantiatable outside of your factory!
Dan Tao
_@Dan Tao_, hmm... You've certainly got a point there. Note however that I did *not* say anywhere in my answer that `Factory<T>` ought to be the *exclusive* creator of items of type `T`. This was merely the most simple example I could think of; perhaps the type name `Factory<T>` suggests too much.
stakx
A: 

It's seldom needed in the sense of being the only way of accomplishing something. But sometimes it's the easiest way to do something.

For example let's say you're writing an object pool. When someone wants to take an object from the pool, it either returns an existing object or simply creates a new one if none is available. You could add the where T : new() constraint to allow yourself to simply write return new T();.

The constraint isn't needed here, as you could've accomplished the same thing by taking a Func<T> in the pool's constructor and using that. Arguably, this method is in fact better, as it's more flexible. But again, new T() is just nice and easy.

Dan Tao