Что означает «где T: class, new ()»? - PullRequest
263 голосов
/ 19 января 2011

Не могли бы вы объяснить, что означает where T : class, new() в следующей строке кода?

void Add<T>(T item) where T : class, new();

Ответы [ 10 ]

289 голосов
/ 19 января 2011

Это ограничение общего параметра T. Он должен быть class (ссылочный тип) и иметь открытый конструктор по умолчанию без параметров.

Это означает, что T не может быть int, float, double, DateTime или любым другим struct (тип значения).

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

142 голосов
/ 19 января 2011

Это ограничения общего типа.В вашем случае их два:

where T : class

Означает, что тип T должен быть ссылочным типом (не типом значения).

where T : new()

Означает, что типT должен иметь конструктор без параметров.Наличие этого ограничения позволит вам сделать что-то вроде T field = new T(); в вашем коде, что вы не смогли бы сделать иначе.

Затем вы объединяете их, используя запятую, чтобы получить:

where T : class, new()
107 голосов
/ 20 мая 2013

где T: struct

Аргумент типа должен быть типом значения.Можно указать любой тип значения, кроме Nullable.См. Использование Обнуляемых Типов (Руководство по программированию в C #) для получения дополнительной информации.

где T: класс

Аргумент типа должен быть ссылочным типом, включая любой класс, интерфейсделегат или тип массива.(См. Примечание ниже.)

где T: new () Аргумент типа должен иметь открытый конструктор без параметров.При использовании в сочетании с другими ограничениями, ограничение new () должно указываться последним.

где T: [имя базового класса]

Аргумент типа должен быть илинаследуется от указанного базового класса.

где T: [имя интерфейса]

Аргумент типа должен быть или реализовывать указанный интерфейс.Можно указать несколько ограничений интерфейса.Ограничительный интерфейс также может быть универсальным.

, где T: U

Аргумент типа, предоставленный для T, должен быть или получен из аргумента, предоставленного для U. Это называетсяограничение обнаженного типа.

16 голосов
/ 26 июня 2017

class & new - это ограничения 2 на параметр универсального типа T.
Соответственно они обеспечивают:

class

Аргумент типа должен быть ссылочным типом;это относится также к любому классу, интерфейсу, делегату или типу массива.

new

Аргумент типа должен иметь открытый конструктор без параметров.При использовании вместе с другими ограничениями ограничение new () должно указываться последним.

Их комбинация означает, что тип T должен быть ссылочным типом (не можетбыть типом значения ) и должен иметь конструктор без параметров.

Пример:

struct MyStruct { } // structs are value types

class MyClass1 { } // no constructors defined, so the class implicitly has a parameterless one

class MyClass2 // parameterless constructor explicitly defined
{
    public MyClass2() { }
}

class MyClass3 // only non-parameterless constructor defined
{
    public MyClass3(object parameter) { }
}

class MyClass4 // both parameterless & non-parameterless constructors defined
{
    public MyClass4() { }
    public MyClass4(object parameter) { }
}

interface INewable<T>
    where T : new()
{
}

interface INewableReference<T>
    where T : class, new()
{
}

class Checks
{
    INewable<int> cn1; // ALLOWED: has parameterless ctor
    INewable<string> n2; // NOT ALLOWED: no parameterless ctor
    INewable<MyStruct> n3; // ALLOWED: has parameterless ctor
    INewable<MyClass1> n4; // ALLOWED: has parameterless ctor
    INewable<MyClass2> n5; // ALLOWED: has parameterless ctor
    INewable<MyClass3> n6; // NOT ALLOWED: no parameterless ctor
    INewable<MyClass4> n7; // ALLOWED: has parameterless ctor

    INewableReference<int> nr1; // NOT ALLOWED: not a reference type
    INewableReference<string> nr2; // NOT ALLOWED: no parameterless ctor
    INewableReference<MyStruct> nr3; // NOT ALLOWED: not a reference type
    INewableReference<MyClass1> nr4; // ALLOWED: has parameterless ctor
    INewableReference<MyClass2> nr5; // ALLOWED: has parameterless ctor
    INewableReference<MyClass3> nr6; // NOT ALLOWED: no parameterless ctor
    INewableReference<MyClass4> nr7; // ALLOWED: has parameterless ctor
}
13 голосов
/ 20 октября 2013

new (): Указание ограничения new () означает, что тип T должен использовать конструктор без параметров, поэтому объект может быть создан из него - см. Конструкторы по умолчанию

class: Значение T должно быть ссылочным типом, поэтому оно не может быть int, float, double, DateTime или другой структурой (тип значения).

    public void MakeCars()
    {
        //This wont compile as researchEngine doesn't have a public constructor and so cant be instantiated.
        CarFactory<ResearchEngine> researchLine = new CarFactory<ResearchEngine>();
        var researchEngine = researchLine.MakeEngine();

        //Can instantiate new object of class with default public constructor
        CarFactory<ProductionEngine> productionLine = new CarFactory<ProductionEngine>();
        var productionEngine = productionLine.MakeEngine();
    }

    public class ProductionEngine { }
    public class ResearchEngine
    {
        private ResearchEngine() { }
    }

    public class CarFactory<TEngine> where TEngine : class, new()
    {
        public TEngine MakeEngine()
        {
            return new TEngine();
        }
    }
6 голосов
/ 19 января 2011

Это означает, что тип T должен быть классом , а иметь конструктор, который не принимает никаких аргументов.

Например, вы должны быть в состоянии сделать это:

T t = new T();
5 голосов
/ 19 января 2011

где (C # ссылка)

Ограничение new () позволяет компилятору знать, что любой предоставленный аргумент типа должен иметь доступный конструктор без параметров - или default-

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

3 голосов
/ 11 марта 2017

Что следует за «Где», это ограничение на общий тип T, который вы объявили, поэтому:

  • class означает, что T должен быть классома не тип значения или структура.

  • new () указывает, что класс T должен иметь открытый конструктор по умолчанию без параметров.

1 голос
/ 19 января 2011

Это часть механизма Generics, где ключевое слово where добавляет ограничения к тем типам, которые должны быть реализованы для использования в качестве параметров типа.

1 голос
/ 19 января 2011

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

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...