C#创建新的T()


159

您可以看到我正在尝试(但失败)执行以下代码:

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()约束的答案。我已经解决了。


27
不,我看不到您在尝试什么和做不到的事情。我看到一段代码可能是一个工作程序的一部分,没有上下文,没有错误消息,也没有解释。
Ben Voigt

17
糟糕,选择错误答案后,我会讨厌它!
David Heffernan

Answers:


409

看看新的约束

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

2
谢谢,队友-我很高兴今天学会了这一点。给定我方法的上下文,我已经准备好了反射解决方案。干杯!
韩山

8
@nulliusinverba-嗯...如果您在问题中显示方法的上下文,那就很好了。
亚历克斯·阿萨

1
@nulliusinverba-在问题中您没有显示需要参数。
亚历克斯·阿萨

1
@Alex-当我读到他的问题时,我认为他不想要参数:S但是为您投票:)
Phill

是否可以使用诸如new(parameters)约束之类的东西?
路易斯·里斯


29

另一种方法是使用反射:

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

谢谢,队友-考虑到方法的上下文,我使用了该解决方案。
韩山

22
与FYI一样,也可以将其编写为Activator.CreateInstance(typeof(T),signature,args); 有关更多详细信息,请参见msdn.microsoft.com/en-us/library/4b0ww1we.aspx
克里斯·巴克斯特

@卡尔加里编码器:type []签名有什么用,您可以直接使用参数调用CreateInstance,而无需显式指定签名。在这两种情况下,如果不存在匹配的构造函数,您都会得到MissingMethodException。
Boris B.

4
即使这是最适合您的答案,但对于社区而言,显然也不是最佳答案。人们在寻找这个问题,实际上是从下面寻找答案。
陷阱

那到底是什么背景?请添加到原始问题。
詹姆斯

18

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

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

并这样称呼它:

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

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



7

由于它被标记为C#4。在开放源代码框架ImpromptuIntereface的情况下,它将使用dlr调用构造函数,当构造函数具有参数时,它比Activator显着快,而当没有参数时,它的速度却可以忽略不计。但是,主要优点是它将正确处理带有C#4.0可选参数的构造函数,而Activator则不会。

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

4

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

  protected T GetObject<T>()
    {
        T obj = default(T);
        obj =Activator.CreateInstance<T>();
        return obj ;
    }
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.