КАТЕГОРИИ:
АстрономияБиологияГеографияДругие языкиДругоеИнформатикаИсторияКультураЛитератураЛогикаМатематикаМедицинаМеханикаОбразованиеОхрана трудаПедагогикаПолитикаПравоПсихологияРиторикаСоциологияСпортСтроительствоТехнологияФизикаФилософияФинансыХимияЧерчениеЭкологияЭкономикаЭлектроника
|
Основные ограниченияВ параметре-типе можно задать не более одного основного ограничения. Основным ограничением может быть ссылочный тип, указывающий на неизолированный класс. Нельзя использовать для этой цели следующие ссылочные типы: 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, этот код не скомпилировался бы, потому что у некоторых ссылочных типов нет открытых конструкторов без параметров.
|