C#创建新T()

Han*_*han 146 .net c# generics .net-4.0 c#-4.0

你可以看到我正在尝试(但没有)使用以下代码:

protected T GetObject()
{
    return new T();
}
Run Code Online (Sandbox Code Playgroud)

任何帮助将不胜感激.

编辑:

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

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

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

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

        return View(obj);
    }
Run Code Online (Sandbox Code Playgroud)

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

Ale*_*Aza 380

看看新约束

public class MyClass<T> where T : new()
{
    protected T GetObject()
    {
        return new T();
    }
}
Run Code Online (Sandbox Code Playgroud)

T可以是没有默认构造函数的类:在这种情况下,new T()它将是一个无效的语句.该new()约束说,T必须有一个默认的构造,这使得new T()法律.

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

public static T GetObject<T>() where T : new()
{
    return new T();
}
Run Code Online (Sandbox Code Playgroud)

如果需要传递参数:

protected T GetObject(params object[] args)
{
    return (T)Activator.CreateInstance(typeof(T), args);
}
Run Code Online (Sandbox Code Playgroud)

  • @nulliusinverba - 嗯...如果你在问题中展示你的方法的上下文会很好. (8认同)
  • 谢谢,伙伴们 - 我很高兴今天学到了这一点.鉴于我的方法的背景,我已经去了反射解决方案.干杯! (2认同)

Ste*_*eve 61

为什么没有人建议Activator.CreateInstance

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

T obj = (T)Activator.CreateInstance(typeof(T));
Run Code Online (Sandbox Code Playgroud)


Sea*_*man 29

另一种方法是使用反射:

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

  • 就像一个FYI一样,这也可以写成Activator.CreateInstance(typeof(T),signature,args); 有关更多详细信息,请参阅http://msdn.microsoft.com/en-us/library/4b0ww1we.aspx. (22认同)
  • 即使这是最适合您的答案,但它显然不是社区中最好的答案.正在寻找这个问题的人正在寻找下面的答案. (4认同)

Joe*_*orn 18

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

T GetObject<T>(Func<T> factory)
{  return factory(); }
Run Code Online (Sandbox Code Playgroud)

并称之为:

string s = GetObject(() => "result");
Run Code Online (Sandbox Code Playgroud)

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


Luk*_*sky 14

新的约束是好的,但如果你需要T是值类型也使用此:

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


jbt*_*ule 7

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

protected T GetObject(params object[] args)
{
    return (T)Impromptu.InvokeConstructor(typeof(T), args);
}
Run Code Online (Sandbox Code Playgroud)


UJS*_*UJS 6

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

  protected T GetObject<T>()
    {
        T obj = default(T);
        obj =Activator.CreateInstance<T>();
        return obj ;
    }
Run Code Online (Sandbox Code Playgroud)