Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Ответы ОСиСП.doc
Скачиваний:
68
Добавлен:
11.05.2015
Размер:
1.78 Mб
Скачать

Основные ограничения

В параметре-типе можно задать не более одного основного ограничения. Основным ограничением может быть ссылочный тип, указывающий на неизолированный класс. Нельзя использовать для этой цели следующие ссылочные типы: System.Object, System.Array, System.Velegate, System.MulticastDelegate, System.ValueType, System.Enum и System.Void.

При задании ограничения ссылочного типа вы обязуетесь перед компилятором, что любой аргумент-тип будет либо того же типа, что и ограничение, либо производного от него типа. Например, как в этом обобщенном классе:

internal sealed class PrimaryConstraintOfStream<T> where T : Stream

{

public void M(T stream)

{

stream.Close(); // OK.

}

}

В этом определении класса на параметр-тип Tналожено основное ограничение Stream (из пространства имен System.IO), сообщающее компилятору, что код, использующий PrimaryConstraintOfStream, должен задавать аргумент-тип Stream или производный от него тип (например, FileStream). Когда параметр-тип не задает основное ограничение, автоматически задается System.Object. Но, если в исходном тексте явно задать System.Object, компиляторC# выдаст ошибку:

«Error CS0702: Constraint cannot be special class 'object'»

«Ошибка CS0702: ограничение не может быть конкретным классом 'object'»

Есть два особых основных ограничения: class и struct. Ограничение class гарантирует компилятору, что указанный аргумент-тип будет ссылочного типа. Этому ограничению удовлетворяют все типы-классы, типы-интерфейсы, типы-делегаты и типы-массивы, как в следующем обобщенном классе:

internal sealed class PrimaryConstraintOfClass<T> where T : class

{

public void M()

{

T temp = null; // Допустимо, потому что T должен быть ссылочного типа.

}

}

В этом примере присвоение temp значения null допустимо, потому что известно, что T— ссылочного типа, а любая переменная ссылочного типа может быть равна null. При отсутствии уTограничений этот код бы не скомпилировался, потому чтоTмог бы быть значимого типа, а переменные значимого типа нельзя приравнять к null.

Ограничение struct гарантирует компилятору, что указанный аргумент-тип будет значимого типа. Этому ограничению удовлетворяют все значимые типы, и перечисления тоже. Но компилятор и CLR рассматривают любой значимый тип System. Nullable<T> как особый, а значимые типы с поддержкой значения null не подходят под это ограничение. Это объясняется тем, что для параметра-типа Nullable<T> действует ограничение struct, а CLR запрещает такие рекурсивные типы, как Nullable<Nullable<T».

Вот пример класса, где параметр-тип ограничивается с помощью struct.

internal sealed class PrimaryConstraintOfStruct<T> where T : struct

{

public static T Factory()

{

// Допускается, потому что у каждого значимого типа неявно

// есть открытый конструктор без параметров,

return new Т();

}

}

В этом примере применение к Tоператораnewправомерно, потому что известно, чтоT— значимого типа, а у всех значимых типов неявно есть открытый конструктор без параметров. Если быTбыл не ограничен, ограничен ссылочным типом или class, этот код не скомпилировался бы, потому что у некоторых ссылочных типов нет открытых конструкторов без параметров.