Относительно использования нового ограничения в С#

Я никогда не использую новое ограничение, потому что использование не ясно для меня. здесь я нашел один образец, но я просто не понимаю его использования. вот код

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

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

{
}

чтобы кто-нибудь попросил меня понять использование нового Constraint с небольшим и легким образцом для использования в реальном мире. спасибо

Ответ 1

В дополнение к Darin answer, что-то вроде этого потерпит неудачу, потому что 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

Ответ 2

Это ограничение требует, чтобы используемый общий тип не был абстрактным и имел конструктор по умолчанию (без параметров), позволяющий вам его называть.

Рабочий пример:

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

Ответ 3

Новое ограничение указывает, что любой аргумент типа в объявлении универсального класса должен иметь открытый конструктор без параметров.

указанный на официальном веб-сайте

Ответ 4

В вашем примере ограничение действует на <T> в объявлении класса. В первом случае требуется, чтобы общий объект T имел конструктор по умолчанию (без параметров). Во втором примере для этого требуется, чтобы T должен иметь конструктор без параметров без параметров и что он должен реализовывать интерфейс IComparable.

Ответ 5

Вы можете читать new(), как если бы это был интерфейс с конструктором. Подобно этому IComparable указывает, что тип T имеет метод CompareTo, новое ограничение указывает, что тип T имеет открытый конструктор.