Hanshan
Hanshan

Reputation: 3764

C# Create New T()

You can see what I'm trying (but failing) to do with the following code:

protected T GetObject()
{
    return new T();
}

Any help would be greatly appreciated.

EDIT:

The context was as follows. I was playing around with a custom controller class for all controllers to derive from, with standardised methods. So in context, I needed to create a new instance of the object of the controller type. So at time of writing, it was something like:

public class GenericController<T> : Controller
{
    ...

    protected T GetObject()
    {
        return (T)Activator.CreateInstance(ObjectType);
    }        

    public ActionResult Create()
    {
        var obj = GetObject()

        return View(obj);
    }

And so I decided reflection was easiest here. I agree that, certainly given the initial statement of the question, the most appropriate answer to mark as correct was the one using the new() constraint. I have fixed that up.

Upvotes: 218

Views: 233485

Answers (8)

KRUM 3
KRUM 3

Reputation: 27

I tried

if (typeof(T).IsValueType || typeof(T) == typeof(string))
                        return default(T);
                    return Activator.CreateInstance<T>();

But when running it it threw this error at return Activator.CreateInstance<T>();

System.MissingMethodException: 'No parameterless constructor defined for this object.'

The types of T that got used where int and List<int>

Upvotes: 0

Steve
Steve

Reputation: 31652

Why hasn't anyone suggested Activator.CreateInstance ?

http://msdn.microsoft.com/en-us/library/wccyzw83.aspx

T obj = (T)Activator.CreateInstance(typeof(T));

Upvotes: 124

UJS
UJS

Reputation: 861

To get this i tried following code :

  protected T GetObject<T>()
    {
        T obj = default(T);
        obj =Activator.CreateInstance<T>();
        return obj ;
    }

Upvotes: 6

Alex Aza
Alex Aza

Reputation: 78487

Take a look at new Constraint

public class MyClass<T> where T : new()
{
    protected T GetObject()
    {
        return new T();
    }
}

T could be a class that does not have a default constructor: in this case new T() would be an invalid statement. The new() constraint says that T must have a default constructor, which makes new T() legal.

You can apply the same constraint to a generic method:

public static T GetObject<T>() where T : new()
{
    return new T();
}

If you need to pass parameters:

protected T GetObject(params object[] args)
{
    return (T)Activator.CreateInstance(typeof(T), args);
}

Upvotes: 526

Sean Thoman
Sean Thoman

Reputation: 7489

Another way is to use reflection:

protected T GetObject<T>(Type[] signature, object[] args)
{
    return (T)typeof(T).GetConstructor(signature).Invoke(args);
}

Upvotes: 31

jbtule
jbtule

Reputation: 31809

Since this is tagged C# 4. With the open sourece framework ImpromptuIntereface it will use the dlr to call the constructor it is significantly faster than Activator when your constructor has arguments, and negligibly slower when it doesn't. However the main advantage is that it will handle constructors with C# 4.0 optional parameters correctly, something that Activator won't do.

protected T GetObject(params object[] args)
{
    return (T)Impromptu.InvokeConstructor(typeof(T), args);
}

Upvotes: 7

Lukas Cenovsky
Lukas Cenovsky

Reputation: 5670

The new constraint is fine, but if you need T being a value type too, use this:

protected T GetObject() {
    if (typeof(T).IsValueType || typeof(T) == typeof(string)) {
        return default(T);
    } else {
       return (T)Activator.CreateInstance(typeof(T));
    }
}

Upvotes: 21

Joel Coehoorn
Joel Coehoorn

Reputation: 416059

Just for completion, the best solution here is often to require a factory function argument:

T GetObject<T>(Func<T> factory)
{  return factory(); }

and call it something like this:

string s = GetObject(() => "result");

You can use that to require or make use of available parameters, if needed.

Upvotes: 19

Related Questions