|
Программирование >> Программирование с использованием ajax
class MyGenericClass<Tl, Т2, Т3> { private TI innerTlObject; public MyGenericClassO innerTlObject = new Tl() ; public TI InnerTlObject { return innerTlObject; Поскольку не известно, каким является тип Т1, ни один из его конструкторов использовать нельзя - возможно, у него даже нет ни одного, а, может быть, у него нет общедоступного конструктора по умолчанию. Без сложного кода, подразумевающего применение приемов, которые будут показаны позже в этом разделе, по сути, о типе Т1 можно делать только предположение, что это тип, который либо унаследован от System.Object, либо может быть упакован в System.Object. Очевидно, это значит, что ничего особого интересного с экземплярами данного типа и любого из тех других типов, которые предоставляются обобщенному классу MyGenericClass, делать нельзя. Без применения рефлексии, которая представляет собой усовершенствованный прием, применяемый для изучения типов во время выполнения (и не рассматриваемый в этой главе), использовать, по сути, можно только сложный код, подобный показанному ниже: public string GetAllTypesAsString () { return TI = + typeof(TI).ToString() + , T2 = + typeof(T2).ToString0 + , T3 = + typeof(T3).ToString0; Помимо этого, разумеется, существует еще кое-что, что можно делать, особенно в случае коллекций, поскольку работа с группами объектов является довольно простым процессом и не требует никаких предположений о типах объектов, что и является одной из веских причин существования обобщенных классов коллекций, которые уже демонстрировались в этой главе. Другое ограничение, о котором тоже нужно знать, состоит в том, что при сравнении значения типа, указанного в обобщенном классе, со значением null, разрешено использовать только операцию == или ! =. То есть следующий код будет работать нормально: . public bool Compare (TI opl, TI op2) { if (opl ?= null && op2 ?= null) return true; else { return false; Если Т1 представляет собой тип-значение, тогда всегда предполагается, что он не может быть нулевым, поэтому в предыдущем коде Compare будет всегда возвращать true. Однако при попытке сравнить два аргумента opl и ор2 компилятор будет выдавать ошибку: public bool Compare (Tl opl, Tl op2) { if (opl = op2) return true; else { return false; Объясняется это тем, что в данном коде предполагается, что Т1 поддерживает операцию ==. Короче говоря, для того чтобы делать нечто по-настоящему интересное с обобщениями, необходимо знать немного больше о типах, которые используются в классе. Ключевое слово default Одной из наиболее главных деталей, которые необходимо знать о типах, используемых для создания экземпляров обобщенных классов, является то, представляют они собой ссылочные типы или типы-значения. Не зная этого, нельзя даже присваивать значения null с помощью кода, показанного ниже: public MyGenericClassО { innerTlObject = null; Если Tl представляет собой тип-значение, тогда InnerTlObject не может иметь значение null, и этот код компилироваться не будет. К счастью, эта проблема была решена, и привело это к появлению нового способа использования для ключевого слова default (применение которого уже демонстрировалось в структурах switch ранее в главе). Выглядит этот способ так: public MyGenericClass() { innerTlObject = default (Tl) ; Теперь в случае, если тип Т1 представляет собой ссылочный тип, InnerTlObject будет присваиваться значение null, а в случае, если он представляет собой тип-значение - значение по умолчанию. Таким значением по умолчанию для числовых типов является О, а у структур каждый из их членов аналогичным образом инициализируется в О или null. Ключевое слово default позволяет делать с назначаемыми обязательными типами немного больше, но для того, чтобы действительно пойти еще дальше, необходимо научиться ограничивать поставляемые типы. Ограничение типов Типы, которые использовались с обобщенными классами до сих пор, называются неограниченными (unbounded), поскольку никакие ограничения касательно того, какими именно они могут быть, на них не накладывались. Ограничения можно накладывать на те типы, которые могут использоваться для создания экземпляра обобщенного класса. Для этого существует несколько способов. Например, можно ограничивать тип только тем, который наследуется от определенного типа. Если взять приведенные ранее классы Animal, Cow и Chicken, то в их случае можно было бы ограничить тип только унаследованным от класса Animal; тогда следующий код работал бы нормально: MyGenericClass<Cow>= new MyGenericClass<Cow>(); А приведенный ниже код, однако, приводил бы к выдаче во время компиляции сообщения об ошибке: MyGenericClass<string>= new MyGenericClass<string> (); Достигается подобное поведение путем использования в определениях классов ключевого слово where: class MyGenericClass<T> where Т : ограничение Здесь за то, что собой представляет накладываемое ограничение, отвечает синтаксис constraint. Подобным образом можно предоставлять и несколько ограничений, отделяя их друг от друга запятыми: class MyGenericClass<T> where Т : ограничение!, ограничение2 Определять ограничения можно как для одного любого, так и для всех требуемых обобщенным классом ограничений с использованием нескольких операторов where: class MyGenericClass<Tl, Т2> where TI : ограничение! where Т2 : ограничение2 Любое из применяемых ограничений должно обязательно идти после указателей наследования: class MyGenericClass<Tl, Т2> : MyBaseClass, IMylnterface where TI : ограничение! where T2 : ограничение2 Доступные варианты ограничений перечислены в табл. 12.5. В случае применения ограничения new(), оно должно обязательно указываться для типа последним. Посредством ограничения base-class можно применять параметр одного типа в качестве ограничения для другого, как показано ниже: class MyGenericClass<Tl, Т2> where Т2 : Т1 Здесь Т2 должен обязательно представлять собой тот же тип, что и Т1, или наследоваться от Т1. Такое ограничение называется простым ограничением типа и означает, что параметр одного обобщенного типа применяется в качестве ограничения для другого.
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |