Добавить в цитаты Настройки чтения

Страница 286 из 502

<b>}</b>

<b>class DefaultDemo {</b>

<b>  static void Main() {</b>

<b>    // Сконструировать объект класса Test, используя ссылочный тип.</b>

<b>    Test&lt;MyClass&gt; x = new Test&lt;MyClass&gt;();</b>

<b>    if (x.obj == null)</b>

<b>      Console.WriteLine(&quot;Переменная x.obj имеет пустое значение &lt;null&gt;.&quot;);</b>

<b>    // Сконструировать объект класса Test, используя тип значения.</b>

<b>    Test&lt;int&gt; у = new Test&lt;int&gt;();</b>

<b>    if (у.obj == 0)</b>

<b>      Console.WriteLine(&quot;Переменная у.obj имеет значение 0.&quot;);</b>

<b>  }</b>

<b>}</b>

Вот к какому результату приводит выполнение этого кода.

<b>Переменная x.obj имеет пустое значение &lt;null&gt;.</b>

<b>Переменная у.obj имеет значение 0.</b>

Обобщенные структуры

В C# разрешается создавать обобщенные структуры. Синтаксис для них такой же, как и для обобщенных классов. В качестве примера ниже приведена программа, в которой создается обобщенная структура XY для хранения координат X, Y.

<b>// Продемонстрировать применение обобщенной структуры,</b>

<b>using System;</b>

<b>// Эта структура является обобщенной,</b>

<b>struct XY&lt;T&gt; {</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&lt;int&gt; xy = new XY&lt;int&gt;(10, 20);</b>

<b>    XY&lt;double&gt; xy2 = new XY&lt;double&gt;(88.0, 99.0);</b>

<b>    Console.WriteLine(xy.X + &quot;, &quot; + xy.Y);</b>

<b>    Console.WriteLine(xy2.X + &quot;, &quot; + xy2.Y);</b>

<b>  }</b>

<b>}</b>

При выполнении этой программы получается следующий результат.

<b>10, 20</b>

<b>88, 99</b>

Как и на обобщенные классы, на обобщенные структуры могут накладываться ограничения. Например, на аргументы типа в приведенном ниже варианте структуры XY накладывается ограничение типа значения.

<b>struct XY&lt;T&gt; 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&lt;T&gt;(T e, uint idx,</b>

<b>                   T[] src, T[] target) {</b>

<b>    // Проверить, насколько велик массив, </b>

<b>    if (target.Length &lt; src.Length + 1) return false;</b>

<b>    // Скопировать содержимое массива src в целевой массив, </b>

<b>    // попутно введя значение е по индексу idx. </b>

<b>    for (int i = 0, j = 0; i &lt; src.Length; i++, j++) {</b>