214

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.

wonea
  • 4,783
  • 17
  • 86
  • 139
Hanshan
  • 3,656
  • 5
  • 29
  • 36

8 Answers8

512

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);
}
Robert Harvey
  • 178,213
  • 47
  • 333
  • 501
Alex Aza
  • 76,499
  • 26
  • 155
  • 134
120

Why hasn't anyone suggested Activator.CreateInstance ?

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

T obj = (T)Activator.CreateInstance(typeof(T));
ChrisCa
  • 10,876
  • 22
  • 81
  • 118
Steve
  • 31,144
  • 19
  • 99
  • 122
31

Another way is to use reflection:

protected T GetObject<T>(Type[] signature, object[] args)
{
    return (T)typeof(T).GetConstructor(signature).Invoke(args);
}
Alex Aza
  • 76,499
  • 26
  • 155
  • 134
Sean Thoman
  • 7,429
  • 6
  • 56
  • 103
  • Thanks, mate - I went with this solution given the context of the method. – Hanshan Jun 30 '11 at 03:35
  • 23
    Just as an FYI, this can alternatively be written as Activator.CreateInstance(typeof(T), signature, args); see http://msdn.microsoft.com/en-us/library/4b0ww1we.aspx for more detail. – Chris Baxter Jun 30 '11 at 04:09
  • @Calgary Coder: What's the use for a type[] signature, you can just call CreateInstance with params directly, without explicitly specifying the signature. In both cases you would get MissingMethodException if a matching constructor does not exist. – Boris B. Jun 30 '11 at 08:19
  • 4
    Even if this is the answer that works best for you, it's obviously not the best one for the community. People looking for this question is looking for the answer from below, really. – Trap Jun 30 '11 at 09:03
  • And what exactly is that context? Please add it to the original question. – James Jun 30 '11 at 11:38
  • @Boris - Signature is only required if you want to explicitly state the parameter types (i.e., have overloads). You are correct that it is typically not required as by default it will find the "best match". – Chris Baxter Jun 30 '11 at 13:20
21

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));
    }
}
Lukas Cenovsky
  • 5,476
  • 2
  • 31
  • 39
19

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.

Joel Coehoorn
  • 399,467
  • 113
  • 570
  • 794
7

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);
}
jbtule
  • 31,383
  • 12
  • 95
  • 128
6

To get this i tried following code :

  protected T GetObject<T>()
    {
        T obj = default(T);
        obj =Activator.CreateInstance<T>();
        return obj ;
    }
UJS
  • 853
  • 1
  • 10
  • 16
0

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>

KRUM 3
  • 27
  • 3