Страница 286 из 502
<b>}</b>
<b>class DefaultDemo {</b>
<b> static void Main() {</b>
<b> // Сконструировать объект класса Test, используя ссылочный тип.</b>
<b> Test<MyClass> x = new Test<MyClass>();</b>
<b> if (x.obj == null)</b>
<b> Console.WriteLine("Переменная x.obj имеет пустое значение <null>.");</b>
<b> // Сконструировать объект класса Test, используя тип значения.</b>
<b> Test<int> у = new Test<int>();</b>
<b> if (у.obj == 0)</b>
<b> Console.WriteLine("Переменная у.obj имеет значение 0.");</b>
<b> }</b>
<b>}</b>
Вот к какому результату приводит выполнение этого кода.
<b>Переменная x.obj имеет пустое значение <null>.</b>
<b>Переменная у.obj имеет значение 0.</b>
Обобщенные структуры
В C# разрешается создавать обобщенные структуры. Синтаксис для них такой же, как и для обобщенных классов. В качестве примера ниже приведена программа, в которой создается обобщенная структура XY для хранения координат X, Y.
<b>// Продемонстрировать применение обобщенной структуры,</b>
<b>using System;</b>
<b>// Эта структура является обобщенной,</b>
<b>struct XY<T> {</b>
<b> T х;</b>
<b> T y;</b>
<b> public XY(T а, T b) {</b>
<b> х = а;</b>
<b> y = b;</b>
<b> }</b>
<b> public T X {</b>
<b> get { return х; }</b>
<b> set { х = value; }</b>
<b> }</b>
<b> public T Y {</b>
<b> get { return y; }</b>
<b> set { y = value; }</b>
<b> }</b>
<b>}</b>
<b>class StructTest {</b>
<b> static void Main() {</b>
<b> XY<int> xy = new XY<int>(10, 20);</b>
<b> XY<double> xy2 = new XY<double>(88.0, 99.0);</b>
<b> Console.WriteLine(xy.X + ", " + xy.Y);</b>
<b> Console.WriteLine(xy2.X + ", " + xy2.Y);</b>
<b> }</b>
<b>}</b>
При выполнении этой программы получается следующий результат.
<b>10, 20</b>
<b>88, 99</b>
Как и на обобщенные классы, на обобщенные структуры могут накладываться ограничения. Например, на аргументы типа в приведенном ниже варианте структуры XY накладывается ограничение типа значения.
<b>struct XY<T> where Т : struct {</b>
<b>// ...</b>
Создание обобщенного метода
Как следует из приведенных выше примеров, в методах, объявляемых в обобщенных классах, может использоваться параметр типа из данного класса, а следовательно, такие методы автоматически становятся обобщенными по отношению к параметру типа. Но помимо этого имеется возможность объявить обобщенный метод со своими собственными параметрами типа и даже создать обобщенный метод, заключенный в необобщенном классе.
Рассмотрим для начала простой пример. В приведенной ниже программе объявляется необобщенный класс ArrayUtils, а в нем — статический обобщенный метод CopyInsert(). Этот метод копирует содержимое одного массива в другой, вводя по ходу дела новый элемент в указанном месте. Метод CopyInsert() можно использовать вместе с массивами любого типа.
<b>// Продемонстрировать применение обобщенного метода, </b>
<b>using System;</b>
<b>// Класс обработки массивов. Этот класс не является обобщенным, </b>
<b>class ArrayUtils {</b>
<b> // Копировать массив, вводя по ходу дела новый элемент. </b>
<b> // Этот метод является обобщенным. </b>
<b> public static bool CopyInsert<T>(T e, uint idx,</b>
<b> T[] src, T[] target) {</b>
<b> // Проверить, насколько велик массив, </b>
<b> if (target.Length < src.Length + 1) return false;</b>
<b> // Скопировать содержимое массива src в целевой массив, </b>
<b> // попутно введя значение е по индексу idx. </b>
<b> for (int i = 0, j = 0; i < src.Length; i++, j++) {</b>