【问题标题】:What are the use cases of having new() in "public T SomeMethod<T>(string item) where T : new();" [closed]在“public T SomeMethod<T>(string item) where T : new();”中有 new() 的用例是什么? [关闭]
【发布时间】:2014-02-28 19:34:59
【问题描述】:

我正在尝试识别 various uses cases 在语句中使用 new()

public T SomeMethod<T>(string item) where T : new();

我知道编译器会确保T 必须有一个默认构造函数。但在所有情况下,这都是有帮助的。

我经历过这个link

【问题讨论】:

  • 当您的泛型方法需要创建泛型类型的实例时,它很有用。除此之外,这个问题的范围很广,可以在这里成为话题。

标签: c# oop generics design-patterns


【解决方案1】:

where T : new() 上的MSDN's own page 列出了最常见的用例:

当您的泛型类创建类型的新实例时,将新约束应用于类型参数,如下例所示:

class ItemFactory<T> where T : new()
{
    public T GetNewItem()
    {
        return new T();
    }
}

约束还要求无参数构造函数是public

【讨论】:

    【解决方案2】:

    如果您需要在代码中的任何地方创建 T 的新实例,这将很有帮助 - 例如,在通用工厂方法中。如果您不确保无参数构造函数,您的代码将永远无法创建实例(因为您不知道构造函数签名会是什么样子)。

    【讨论】:

      【解决方案3】:

      如果您的泛型方法/类必须创建给定类型的实例,这很有用。如果您有一个创建泛型类型的方法:

      public void DoWork<T>() where T : new() {
          var thing = new T();
      }
      

      对比:

      public void DoWork<T>() {
          var thing = new T(); - runtime says "wtf are you doing? i cant create a 
                                 new T because T might not have a public  
                                 parameterless constructor"
      }
      

      【讨论】:

      • “T”不可能没有构造函数。私有/受保护/公共...带/不带参数..或默认构造函数。但至少总会有一个。
      • @Amby - 不错的收获。一边走路一边打字,发帖前没有仔细阅读。
      【解决方案4】:
      public T SomeMethod<T>(string item) where T : new();
      

      将“T”约束为具有默认(无参数)构造函数的类型。

      您将无法使用此类型(编译失败)

      public class CustomTypeA{
           public CustomTypeA(int count){}
      }
      

      虽然这个是允许的,

      public class CustomTypeB{
      }
      

      还有这个,

      public class CustomTypeC{
           public CustomTypeC(){}
      }
      

      另请注意,这种类型的约束将接受所有 Struct T(int、double 等)。因为结构总是有一个默认的构造函数。

      鉴于这些可能性, 它很有用:1)当你想限制到上面的列表时。 2) 当你想在不使用反射的情况下实例化(调用它的构造函数)这种类型时。

      【讨论】:

        【解决方案5】:

        此约束的要点是编译器将保证您为T 指定的任何类型都将具有公共无参数构造函数,从而允许此代码工作:

        var instance = new T();
        

        但是请注意,上面的代码实际上会变成对Activator.CreateInstance(Type) 的调用,这意味着您得到的只是保证。您可以自己调用Activator.CreateInstance 方法,但是除非您添加约束,否则您无法保证该类型实际上具有无参数构造函数。

        【讨论】:

          猜你喜欢
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          • 2016-08-28
          • 1970-01-01
          • 1970-01-01
          • 1970-01-01
          相关资源
          最近更新 更多