C#创建新T()

时间:2011-06-30 03:16:28

标签: c# .net generics c#-4.0 .net-4.0

您可以看到我正在尝试(但未通过)以下代码:

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

非常感谢任何帮助。

编辑:

背景如下。我正在使用标准化方法为所有控制器提供自定义控制器类。所以在上下文中,我需要创建一个控制器类型对象的新实例。所以在撰写本文时,它就像是:

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

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

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

        return View(obj);
    }

所以我决定这里的反思最简单。我同意,当然在给出问题的初始陈述时,标记为正确的最合适的答案是使用new()约束的答案。我已经修好了。

7 个答案:

答案 0 :(得分:361)

查看new Constraint

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

T可以是没有默认构造函数的类:在这种情况下,new T()将是无效语句。 new()约束表明T必须有默认构造函数,这使得new T()合法。

您可以将相同的约束应用于通用方法:

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

如果您需要传递参数:

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

答案 1 :(得分:54)

为什么没有人建议Activator.CreateInstance

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

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

答案 2 :(得分:28)

另一种方法是使用反射:

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

答案 3 :(得分:18)

为了完成,这里最好的解决方案通常是需要一个工厂函数参数:

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

并称之为:

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

如果需要,您可以使用它来要求或使用可用参数。

答案 4 :(得分:14)

new constraint很好,但是如果你需要T也是值类型,请使用:

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

答案 5 :(得分:7)

因为它被标记为C#4。使用开放式源框架ImpromptuIntereface它将使用dlr来调用构造函数,当构造函数具有参数时,它比Activator快得多,而当它没有时,它会慢得多。但是主要的优点是它将正确处理具有C#4.0可选参数的构造函数,这是Activator不会做的。

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

答案 6 :(得分:4)

为了得到这个,我尝试了以下代码:

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