Не могли бы вы объяснить мне, что означает where T : class, new()
в следующей строке кода?
void Add<T>(T item) where T : class, new();
Не могли бы вы объяснить мне, что означает where T : class, new()
в следующей строке кода?
void Add<T>(T item) where T : class, new();
Это ограничение на общий параметр T
. Он должен быть class
(ссылочный тип) и должен иметь открытый конструктор по умолчанию без параметров.
Это означает, что T
не может быть int
, float
, double
, DateTime
или любым другим struct
(тип значения).
Это может быть string
или любой другой настраиваемый ссылочный тип, если он имеет конструктор по умолчанию или без параметров.
Это общие ограничения типа. В вашем случае их два:
where T : class
означает, что тип T
должен быть ссылочным типом (а не типом значения).
where T : new()
означает, что тип T
должен иметь конструктор без параметров. Наличие этого ограничения позволит вам сделать что-то вроде T field = new T();
в вашем коде, которое вы не смогли бы сделать иначе.
Затем вы комбинируете два, используя запятую, чтобы получить:
where T : class, new()
, где T: struct
Аргумент типа должен быть типом значения. Можно указать любой тип значения, кроме Nullable. Дополнительную информацию см. В разделе Использование нулевых типов (Руководство по программированию на С#).
, где T: class
Аргумент типа должен быть ссылочным типом, включая любой класс, интерфейс, делегат или тип массива. (См. Примечание ниже.)
, где T: new() Аргумент типа должен иметь открытый конструктор без параметров. При использовании в сочетании с другими ограничениями ограничение new() должно быть указано последним.
, где T: [имя базового класса]
Аргумент типа должен быть или выводиться из указанного базового класса.
, где T: [имя интерфейса]
Аргумент типа должен быть или реализовать указанный интерфейс. Можно указать несколько ограничений интерфейса. Сжатый интерфейс также может быть общим.
, где T: U
Аргумент типа, предоставленный для T, должен быть или получен из аргумента, предоставленного для U. Это называется ограничением голого типа.
new(): Задание средства ограничения типа new() означает, что тип T должен использовать конструктор без параметров, поэтому объект может быть создан из него - см. Default конструкторы
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();
}
}
Это означает, что тип T
должен быть классом и иметь конструктор, который не принимает никаких аргументов.
Например, вы должны иметь возможность сделать это:
T t = new T();
Новое() Constraint позволяет компилятору знать, что любой аргумент типа должен иметь доступный конструктор без параметров - или по умолчанию -
Итак, должно быть, T
должен быть классом и иметь доступный без параметров - или конструктор по умолчанию.
class
и new
равны 2 ограничения для параметра типового типа T
.
Соответственно они обеспечивают:
class
Аргумент типа должен быть ссылочным типом; это относится также к любому классу, интерфейсу, делегированию или типу массива.
new
Аргумент типа должен иметь открытый конструктор без параметров. При использовании вместе с другими ограничениями ограничение new() должно быть указано последним.
Их комбинация означает, что тип T
должен быть Reference Type (не может быть Тип значения) и должен иметь конструктор без параметров.
Пример:
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
}
здесь был похожий вопрос, который задал
Он вызвал "ограничение" на общий параметр T. Это означает, что T должен быть ссылочным типом (классом) и что он должен иметь общедоступный конструктор по умолчанию.
Это часть механизма Generics, где ключевое слово where добавляет ограничения к тем, какие типы должны реализовывать, чтобы использоваться в качестве параметров типа.
Что происходит после того, как "Где" является ограничением на общий тип T, который вы объявили, так:
class означает, что T должен быть классом, а не типом значения или структурой.
new() указывает, что класс T должен иметь открытый конструктор по умолчанию, заданный по умолчанию.