问题 关于在c#中使用新约束


我从不使用新的约束,因为我不清楚使用它。在这里,我发现了一个样本,但我只是不明白使用。这是代码

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

public class ItemFactory2<T> where T : IComparable, new()

{
}

所以任何人都请让我理解使用新的Constraint与小而简单的样品,以供现实世界使用。谢谢


9445
2018-01-25 12:40


起源



答案:


此外 达林的回答这样的事情会失败,因为 Bar 没有无参数构造函数

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

   class Foo : ItemFactory<Bar>
   {

   }

   class Bar
   {
      public Bar(int a)
      {

      }
   }

实际错误是: 'Bar' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ItemFactory<T>'

以下也会失败:

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

实际错误是: Cannot create an instance of the variable type 'T' because it does not have the new() constraint


6
2018-01-25 12:50



我只需要知道... new()将始终用于参数较少的构造函数。如果构造函数接受参数那么我们不能使用像T:new()那样的语法?请讨论。谢谢 - Thomas


答案:


此外 达林的回答这样的事情会失败,因为 Bar 没有无参数构造函数

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

   class Foo : ItemFactory<Bar>
   {

   }

   class Bar
   {
      public Bar(int a)
      {

      }
   }

实际错误是: 'Bar' must be a non-abstract type with a public parameterless constructor in order to use it as parameter 'T' in the generic type or method 'ItemFactory<T>'

以下也会失败:

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

实际错误是: Cannot create an instance of the variable type 'T' because it does not have the new() constraint


6
2018-01-25 12:50



我只需要知道... new()将始终用于参数较少的构造函数。如果构造函数接受参数那么我们不能使用像T:new()那样的语法?请讨论。谢谢 - Thomas


此约束要求使用的泛型类型是非抽象的,并且它具有允许您调用它的默认(无参数)构造函数。

工作范例:

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

这显然现在会迫使你为作为泛型参数传递的类型有一个无参数构造函数:

var factory1 = new ItemFactory<Guid>(); // OK
var factory2 = new ItemFactory<FileInfo>(); // doesn't compile because FileInfo doesn't have a default constructor
var factory3 = new ItemFactory<Stream>(); // doesn't compile because Stream is an abstract class

非工作示例:

class ItemFactory<T>
{
    public T GetNewItem()
    {
        return new T(); // error here => you cannot call the constructor because you don't know if T possess such constructor
    }
}

11
2018-01-25 12:43



默认的ctor是空的ctor;) - Novakov
@Novakov:不对。默认的ctor是没有参数的ctor。但它的身体不需要是空的,它可以包含代码。 - Daniel Hilgarth
@Daniel:我一直认为如果没有定义ctor,默认ctor是由编译器生成的,而'default'意味着它具有默认(调用基类ctor)行为。 - Novakov
@Novakov:你部分正确:如果你的类没有定义构造函数本身,编译器会生成一个没有参数的构造函数,什么也不做,并调用基类的默认构造函数。那是对的。但是,术语“默认构造函数”表示(1)公共和(2)没有参数的所有构造函数。 - Daniel Hilgarth
@Daniel:很高兴知道,谢谢你的解释 - Novakov


新约束指定泛型类声明中的任何类型参数都必须具有公共无参数构造函数。

引自官方的话 网站


0
2018-01-25 12:43





在您的示例中,约束作用于 <T> 在课堂宣言中。在第一种情况下,它要求通用 T object有一个默认的(无参数)构造函数。在第二个例子中,它需要 T 应该有一个默认的无参数构造函数,它必须实现 IComparable 接口。


0
2018-01-25 12:46





你可以阅读 new() 好像它是一个带有构造函数的接口。就像IComparable指定类型T具有方法CompareTo一样,新约束指定类型T具有公共构造函数。


-1
2018-01-25 12:44