ChatGPT解决这个技术问题 Extra ChatGPT

C# 创建新的 T()

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

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

不,我看不出你在尝试什么但没有做。我看到一段代码可能是工作程序的一部分,没有上下文,没有错误消息,也没有解释。
哦,我讨厌选择错误的答案!

R
Robert Harvey

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

谢谢,伙计-我很高兴今天学到了这一点。鉴于我的方法的上下文,我选择了反射解决方案。干杯!
@nulliusinverba - 嗯......如果你在问题中展示你的方法的上下文会很好。
@nulliusinverba - 您没有在问题中显示您需要参数。
@Alex - 当我读到他的问题时,我认为他不想要参数:S Up-vote for you 然而:)
是否可以使用类似 new(parameters) 约束的东西?
C
ChrisCa

为什么没有人建议 Activator.CreateInstance

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

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

A
Alex Aza

另一种方法是使用反射:

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

谢谢,伙计-鉴于该方法的上下文,我采用了此解决方案。
仅供参考,这也可以写成 Activator.CreateInstance(typeof(T), signature, args);有关详细信息,请参阅 msdn.microsoft.com/en-us/library/4b0ww1we.aspx
@Calgary Coder: type[] 签名有什么用,您可以直接使用参数调用 CreateInstance ,而无需明确指定签名。在这两种情况下,如果不存在匹配的构造函数,您都会得到 MissingMethodException。
即使这是最适合您的答案,它显然也不是最适合社区的答案。寻找这个问题的人实际上是在寻找下面的答案。
那究竟是什么背景?请将其添加到原始问题中。
L
Lukas Cenovsky

new constraint 很好,但如果您也需要 T 作为值类型,请使用:

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

J
Joel Coehoorn

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

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

并称其为:

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

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


j
jbtule

由于这被标记为 C# 4。使用开源框架 ImpromptuIntereface,它将使用 dlr 调用构造函数,当你的构造函数有参数时,它比 Activator 快得多,而当它没有参数时,速度可以忽略不计。然而,主要优点是它可以正确处理带有 C# 4.0 可选参数的构造函数,而 Activator 不会这样做。

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

U
UJS

为此,我尝试了以下代码:

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