Відповіді:
Це обмеження для загального параметра T
. Він повинен бути class
(тип посилання) і повинен мати відкритий конструктор за замовчуванням без параметрів.
Це означає T
не може бути int
, float
, double
, DateTime
або будь-який інший struct
(тип значення).
Це може бути string
будь-який або інший користувацький тип посилань, якщо він має конструктор за замовчуванням або без параметрів.
new()
точно визначає «повинен мати конструктор громадських без параметрів»
Це загальні обмеження типу. У вашому випадку їх два:
where T : class
Означає, що тип T
повинен бути еталонним типом (а не типом значення).
where T : new()
Значить, тип T
повинен мати конструктор без параметрів. Наявність цього обмеження дозволить вам зробити щось на кшталт T field = new T();
свого коду, чого б ви не могли зробити інакше.
Потім ви комбінуєте два, використовуючи кому:
where T : class, new()
де T: структура
Аргумент типу повинен бути типом значення. Будь-який тип значення, крім Nullable, може бути визначений. Додаткову інформацію див. У розділі Використання змінних типів (Посібник з програмування C #).
де Т: клас
Аргумент типу повинен бути посилальним типом, включаючи будь-який клас, інтерфейс, делегат або тип масиву. (Див. Примітку нижче.)
де T: new () Аргумент типу повинен мати відкритий конструктор без параметрів. При використанні спільно з іншими обмеженнями нове () обмеження повинно бути вказане останньою.
де T: [назва базового класу]
Аргумент типу повинен бути або походити із зазначеного базового класу.
де T: [назва інтерфейсу]
Аргумент типу повинен бути або реалізувати вказаний інтерфейс. Можна вказати кілька обмежень інтерфейсу. Обмежувальний інтерфейс також може бути загальним.
де T: U
Аргумент типу, наданий для T, повинен бути або походити від аргументу, наданого для U. Це називається обмеженням голого типу.
class
& new
є двома обмеженнями для параметра загального типуT
.
Відповідно, вони забезпечують:
class
Аргумент типу повинен бути еталонним типом; це стосується також будь-якого типу класу, інтерфейсу, делегата або типу масиву.
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
}
new (): Вказуючи новий () обмежувальний засіб типу T повинен використовувати конструктор без параметрів, щоб об'єкт міг бути екземпляром з нього - див. Конструктори за замовчуванням .
клас: Значення 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();
Новий () обмеження дозволяє компілятору знати, що будь-який доданий аргумент повинен мати доступний конструктор без параметрів - або за замовчуванням--
Отже, він повинен бути T
класом і мати доступний конструктор без параметрів - або за замовчуванням.
Що виникає після "Де" - це обмеження для загального типу T, який ви заявили, так:
клас означає, що Т повинен бути класом, а не типом значення або структурою.
new () вказує, що для класу T повинен бути визначений загальнодоступний конструктор за замовчуванням без параметрів.
Це називається "обмеженням" на загальний параметр T. Це означає, що T повинен бути посилальним типом (класом) і що він повинен мати публічний конструктор за замовчуванням.
Це частина механізму Generics, де ключове слово де додає обмеження для того, які типи потрібно реалізувати, щоб використовуватись як параметри типу.