Coder Perfect

New T in C# ()

Problem

With the following code, you can see what I’m attempting (but failing) to achieve:

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

Any assistance would be really helpful.

EDIT:

The following was the situation: I was tinkering with a custom controller class that all controllers would inherit from, complete with standard methods. So, in this case, I needed to create a new instance of the controller type object. So, at the time of writing, it looked like this:

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

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

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

        return View(obj);
    }

As a result, I thought that the best place to reflect was here. Given the question’s opening statement, I believe that the most suitable solution to mark as right was the one that used the new() constraint. That has been resolved.

Asked by Hanshan

Solution #1

Take a peek at the new Constraint feature.

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

T could be a class without a default constructor, in which case new T() is an invalid statement. The new() restriction requires T to have a default constructor, thus new T() is valid.

A generic method can be subjected to the same constraint:

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

If you need to pass parameters, do so as follows:

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

Answered by Alex Aza

Solution #2

Why hasn’t Activator.CreateInstance been suggested?

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

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

Answered by Steve

Solution #3

Another option is to reflect:

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

Answered by Sean Thoman

Solution #4

The new constraint is good, but if T must also be a value type, use the following:

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

Answered by Lukas Cenovsky

Solution #5

For the sake of completeness, requiring a factory function argument is frequently the ideal solution:

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

and rename it:

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

If necessary, you can utilize this to demand or use accessible parameters.

Answered by Joel Coehoorn

Post is based on https://stackoverflow.com/questions/6529611/c-sharp-create-new-t