Що означає "де T: клас, новий ()"?


Відповіді:


329

Це обмеження для загального параметра T. Він повинен бути class(тип посилання) і повинен мати відкритий конструктор за замовчуванням без параметрів.

Це означає Tне може бути int, float, double, DateTimeабо будь-який інший struct(тип значення).

Це може бути stringбудь-який або інший користувацький тип посилань, якщо він має конструктор за замовчуванням або без параметрів.


5
Просто для уточнення, якщо у вас немає класового застереження як частини T, де T ..., тоді можна безпечно використовувати int, float, double та ін.
AboutDev

1
@ AboutDev правильно, вам не доведеться ставити обмеження для параметра загального типу. Але якщо ви створюєте загальний, який розраховує працювати лише на типи посилань або значень, то вам слід вказати. Без обмежень можна очікувати типів посилань (класів) або типів значень (структури (int, float, double ...)).
NerdFury

1
А як там, де T: [ім'я інтерфейсу], new ()? Вам все-таки потрібно мати конструктор без параметрів?
Вінс Тіно

3
Щоб уточнити коментар Джастіна, порожній конструктор не має висловлювань (як конструктор за замовчуванням), тоді як конструктор без параметрів може містити заяви (наприклад, ініціалізація списку).
DharmaTurtle

@VinceTino: new()точно визначає «повинен мати конструктор громадських без параметрів»
Flater

162

Це загальні обмеження типу. У вашому випадку їх два:

where T : class

Означає, що тип Tповинен бути еталонним типом (а не типом значення).

where T : new()

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

Потім ви комбінуєте два, використовуючи кому:

where T : class, new()

Хороші бали для другого і третього, просто для додання інформації, я думаю, другий момент корисний при виконанні рефлексії в родовому типі. напр. T t = новий T (); t.GetType (). GetProperty ("ID"). SetValue (t, uniqueId, null);
Джеррі Лян

1
Я вважаю, що зайве говорити, де T: class, new (), оскільки new () вже передбачає клас, оскільки структури не можуть мати конструктори за замовчуванням.
DharmaTurtle

@DharmaTurtle, "структури не можуть містити явних конструкторів без параметрів", не означає, що їх немає, це говорить про те, що ви не можете його визначити. джерело: msdn.microsoft.com/tr-tr/library/aa288208(v=vs.71).aspx
rustem

121

де T: структура

Аргумент типу повинен бути типом значення. Будь-який тип значення, крім Nullable, може бути визначений. Додаткову інформацію див. У розділі Використання змінних типів (Посібник з програмування C #).

де Т: клас

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

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

де T: [назва базового класу]

Аргумент типу повинен бути або походити із зазначеного базового класу.

де T: [назва інтерфейсу]

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

де T: U

Аргумент типу, наданий для T, повинен бути або походити від аргументу, наданого для U. Це називається обмеженням голого типу.


23
Це було корисно, але посилання на джерело .
Скеан

26

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
}

1
Гарна демонстрація. Дякую.
Субхан Алі

15

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();
    }
}

6

Це означає, що тип Tповинен бути класом і мати конструктор, який не бере жодних аргументів.

Наприклад, ви повинні зробити це:

T t = new T();

1
не просто конструктор, а конструктор, який не бере аргументів.
NerdFury

@NerdFury: Дякую Це важливий біт. Виправлено.
Еван Мулавський

5

де (C # посилання)

Новий () обмеження дозволяє компілятору знати, що будь-який доданий аргумент повинен мати доступний конструктор без параметрів - або за замовчуванням--

Отже, він повинен бути Tкласом і мати доступний конструктор без параметрів - або за замовчуванням.


4

Що виникає після "Де" - це обмеження для загального типу T, який ви заявили, так:

  • клас означає, що Т повинен бути класом, а не типом значення або структурою.

  • new () вказує, що для класу T повинен бути визначений загальнодоступний конструктор за замовчуванням без параметрів.


1

Це називається "обмеженням" на загальний параметр T. Це означає, що T повинен бути посилальним типом (класом) і що він повинен мати публічний конструктор за замовчуванням.


1

Це частина механізму Generics, де ключове слово де додає обмеження для того, які типи потрібно реалізувати, щоб використовуватись як параметри типу.


0

при використанні класу з обмеженнями, це означає, що ви можете використовувати лише тип посилання, інша річ, яку слід додати, це коли використовувати обмеження new () , це повинно бути останнє, що ви пишете в умовах обмежень.

Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.