ChatGPT解决这个技术问题 Extra ChatGPT

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.

No, I don't see what you're trying and failing to do. I see a piece of code that could be part of a working program, with no context, no error message, and no explanation.
Aw, I hate it when the wrong answer is selected!

R
Robert Harvey

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);
}

Thanks, mate - I am glad to have learned this today. Given the context of my method, I've gone for the reflection solution. Cheers!
@nulliusinverba - hmm... it would be nice if you showed the context of your method in the question.
@nulliusinverba - you didn't show in the question that you needed parameters.
@Alex - When I read his question I assumed he didn't want parameters :S Up-vote for you however :)
Is it possible to use something like new(parameters) constraint?
C
ChrisCa

Why hasn't anyone suggested Activator.CreateInstance ?

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

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

A
Alex Aza

Another way is to use reflection:

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

Thanks, mate - I went with this solution given the context of the method.
Just as an FYI, this can alternatively be written as Activator.CreateInstance(typeof(T), signature, args); see msdn.microsoft.com/en-us/library/4b0ww1we.aspx for more detail.
@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.
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.
And what exactly is that context? Please add it to the original question.
L
Lukas Cenovsky

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));
    }
}

J
Joel Coehoorn

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.


j
jbtule

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);
}

U
UJS

To get this i tried following code :

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