class Gen
В этом объявлении оператор where
уведомляет компилятор о том, что аргумент типа, привязанный к параметру типа V, должен быть таким же, как и аргумент типа, привязанный к параметру типа Т, или же наследовать от него. Если подобная связь отсутствует при объявлении объекта типа Gen
, то во время компиляции возникнет ошибка. Такое ограничение на параметр типа называется
// Установить связь между двумя параметрами типа.
using System;
class A {
//...
}
class В : A {
// ...
}
// Здесь параметр типа V должен наследовать от параметра типа Т.
class Gen
// ...
}
class NakedConstraintDemo {
static void Main() {
// Это объявление вполне допустимо, поскольку
// класс В наследует от класса А.
Gen х = new Gen();
// А это объявление недопустимо, поскольку
// класс А-.не наследует от класса В. .
// Gen у = new Gen();
}
}
Обратите внимание на то, что класс В наследует от класса А. Проанализируем далее оба объявления объектов класса Gen
в методе Main(). Как следует из комментария к первому объявлению
Gen х = new Gen();
оно вполне допустимо, поскольку класс В наследует от класса А. Но второе объявление
// Gen у = new Gen();
недопустимо, поскольку класс А не наследует от класса В.
С параметром типа может быть связано несколько ограничений. В этом случае ограничения указываются списком через запятую. В этом списке первым должно быть указано ограничение class
либо struct
, если оно присутствует, или же ограничение на базовый класс, если оно накладывается. Указывать ограничения class
или struct
одновременно с ограничением на базовый класс не разрешается. Далее по списку должно следовать ограничение на интерфейс, а последним по порядку — ограничение new()
. Например, следующее объявление считается вполне допустимым.
class Gen
// ...
В данном случае параметр типа Т должен быть заменен аргументом типа, наследующим от класса MyClass
, реализующим интерфейс IMylnterface
и использующим конструктор без параметра.
Если же в обобщении используются два или более параметра типа, то ограничения на каждый из них накладываются с помощью отдельного оператора where, как в приведенном ниже примере.
// Использовать несколько операторов where,
using System;
// У класса Gen имеются два параметра типа, и на оба накладываются
// ограничения с помощью отдельных операторов where,
class Gen
where V : struct {
T ob1;
V ob2;
public Gen(T t, V v) {
ob1 = t;
ob2 = v;
}
}
class MultipleConstraintDemo {
static void Main() {
// Эта строка кода вполне допустима, поскольку
// string — это ссылочный тип, a int — тип значения.
Gen
//А следующая строка кода недопустима, поскольку
// bool не относится к ссылочному типу.
// Gencbool, int> obj = new Gencbool, int>(true, 11);
}
}
В данном примере класс Gen принимает два аргумента с ограничениями, накладываемыми с помощью отдельных операторов where. Обратите особое внимание на объявление этого класса.
class GenCT, V> where T : class
where V : struct {
Как видите, один оператор where
отделяется от другого только пробелом. Другие знаки препинания между ними не нужны и даже недопустимы.
Получение значения, присваиваемого параметру типа по умолчанию