Не могли бы вы объяснить мне, что означает 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
или любой другой настраиваемый ссылочный тип, если он имеет конструктор по умолчанию или конструктор без параметров.
new()
точно указывает, что должен иметь общедоступный конструктор без параметров
- person Flater; 09.11.2019
new()
также исключает конструкторы с одним параметром и значением по умолчанию для него ... По крайней мере, я считаю это неинтуитивным.
- person mBardos; 29.01.2021
Это ограничения универсального типа. В вашем случае их два:
where T : class
Означает, что тип T
должен быть ссылочным типом (а не типом значения).
where T : new()
Означает, что тип T
должен иметь конструктор без параметров. Наличие этого ограничения позволит вам сделать в коде что-то вроде T field = new T();
, чего вы не смогли бы сделать иначе.
Затем вы объединяете два, используя запятую, чтобы получить:
where T : class, new()
где T: struct
Аргумент типа должен быть типом значения. Можно указать любой тип значения, кроме Nullable. Дополнительные сведения см. В разделе Использование типов, допускающих значение NULL (Руководство по программированию на C #).
где T: класс
Аргумент типа должен быть ссылочным типом, включая любой тип класса, интерфейса, делегата или массива. (См. Примечание ниже.)
where T: new () Аргумент типа должен иметь общедоступный конструктор без параметров. При использовании вместе с другими ограничениями ограничение new () должно быть указано последним.
где T: [название базового класса]
Аргумент типа должен быть указанным базовым классом или производным от него.
где T: [название интерфейса]
Аргумент типа должен быть или реализовывать указанный интерфейс. Можно указать несколько ограничений интерфейса. Ограничивающий интерфейс также может быть общим.
где T: U
Аргумент типа, предоставленный для T, должен быть или производным от аргумента, предоставленного для U. Это называется ограничением простого типа.
class
& new
- это 2 ограничений для параметр универсального типа T
.
Соответственно, они обеспечивают:
class
Аргумент типа должен быть ссылочным типом; это применимо также к любому типу класса, интерфейса, делегата или массива.
new
Аргумент типа должен иметь общедоступный конструктор без параметров. При использовании вместе с другими ограничениями ограничение new () должно быть указано последним.
Их сочетание означает, что тип T
должен быть Reference Тип (не может быть Тип значения) и должен иметь конструктор без параметров.
Пример:
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
}
new (): указание ограничения new () означает, что тип T должен использовать конструктор без параметров, поэтому из него можно создать экземпляр объекта - см. Конструкторы по умолчанию.
class: Означает, что T должен быть ссылочным типом, поэтому он не может быть int, float, double, DateTime или другой структурой (типом значения).
public void MakeCars()
{
//This won't compile as researchEngine doesn't have a public constructor and so can't 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();
Ограничение new () позволяет компилятору знать, что любой предоставленный аргумент типа должен иметь доступный конструктор без параметров или конструктор по умолчанию.
Так и должно быть, T
должен быть классом и иметь доступный конструктор без параметров или конструктор по умолчанию.
То, что идет после "Где", является ограничением для объявленного вами универсального типа T, поэтому:
class означает, что T должен быть классом, а не типом значения или структурой.
new () указывает, что для класса T должен быть определен общедоступный конструктор по умолчанию без параметров.
Это называется «ограничением» для универсального параметра T. Это означает, что T должен быть ссылочным типом (классом) и должен иметь общедоступный конструктор по умолчанию.
Это часть механизма Generics, где ключевое слово where добавляет ограничения к тому, какие типы должны быть реализованы, чтобы их можно было использовать в качестве параметров типа.
при использовании класса в ограничениях это означает, что вы можете использовать только ссылочный тип. Еще одна вещь, которую следует добавить, - это когда использовать ограничение new (), это должно быть последнее, что вы напишите в условиях ограничений.