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

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

<b>    return v + 2.0; </b>

<b>  } </b>

<b>  // Определить метод увеличения на два каждого</b>

<b>  // последующего значения координат объекта типа ThreeD. </b>

<b>  static ThreeD ThreeDPlusTwo(ThreeD v) { </b>

<b>    if(v==null) return new ThreeD(0, 0, 0); </b>

<b>    else return new ThreeD(v.x + 2, v.y + 2, v.z + 2); </b>

<b>  } </b>

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

<b>    // Продемонстрировать генерирование</b>

<b>    // последовательного ряда значений типа int. </b>

<b>    ByTwos&lt;int&gt; intBT = new ByTwos&lt;int&gt;(IntPlusTwo); </b>

<b>    for(int i=0; i &lt; 5; i++) </b>

<b>      Console.Write(intBT.GetNext() + &quot;  &quot;); </b>

<b>    Console.WriteLine(); </b>

<b>    // Продемонстрировать генерирование</b>

<b>    // последовательного ряда значений типа double. </b>

<b>    ByTwos&lt;double&gt; dblBT = new ByTwos&lt;double&gt;(DoublePlusTwo); </b>

<b>    dblBT.SetStart(11.4); </b>

<b>    for(int i=0; i &lt; 5; i++) </b>

<b>      Console.Write(dblBT.GetNext() + &quot;  &quot;); </b>

<b>    Console.WriteLine(); </b>

<b>    // Продемонстрировать генерирование последовательного ряда</b>

<b>    // значений координат объекта типа ThreeD. </b>

<b>    ByTwos&lt;ThreeD&gt; ThrDBT = new ByTwos&lt;ThreeD&gt;(ThreeDPlusTwo); </b>

<b>    ThreeD coord; </b>

<b>    for(int i=0; i &lt; 5; i++) { </b>

<b>      coord = ThrDBT.GetNext(); </b>

<b>      Console.Write(coord.x + &quot;,&quot; + </b>

<b>                    coord.y + &quot;,&quot; + </b>

<b>                    coord.z + &quot;  &quot;); </b>

<b>    } </b>

<b>    Console.WriteLine(); </b>

<b>  } </b>

<b>}</b>

Этот код выдает следующий результат.

<b>2 4 6 8 10</b>

<b>13.4 15.4 17.4 19.4 21.4</b>

<b>0,0,0 2,2,2 4,4,4 6,6,6 8,8,8</b>

В данном примере кода имеется ряд любопытных моментов. Прежде всего обратите внимание на объявление интерфейса ISeries в следующей строке кода.

<b>public interface ISeries&lt;T&gt; {</b>

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

А теперь обратите внимание на следующее объявление класса ByTwos, реализующего интерфейс ISeries.

<b>class ByTwos&lt;T&gt; : ISeries&lt;T&gt; {</b>

Параметр типа Т указывается не только при объявлении класса ByTwos, но и при объявлении интерфейса ISeries. И это очень важно. Ведь класс, реализующий обобщенный вариант интерфейса, сам должен быть обобщенным. Так, приведенное ниже объявление недопустимо, поскольку параметр типа Т не определен.

<b>class ByTwos : ISeries&lt;T&gt; { // Неверно!</b>

Аргумент типа, требующийся для интерфейса ISeries, должен быть передан классу ByTwos. В противном случае интерфейс никак не сможет получить аргумент типа.

Далее переменные, хранящие текущее значение в последовательном ряду (val) и его начальное значение (start), объявляются как объекты обобщенного типа Т. После этого объявляется делегат IncByTwo. Этот делегат определяет форму метода, используемого для увеличения на два значения, хранящегося в объекте типа Т. Для того чтобы в классе ByTwos могли обрабатываться данные любого типа, необходимо каким-то образом определить порядок увеличения на два значения каждого типа данных. Для этого конструктору класса ByTwos передается ссылка на метод, выполняющий увеличение на два. Эта ссылка хранится в переменной экземпляра делегата incr. Когда требуется сгенерировать следующий элемент в последовательном ряду, этот метод вызывается с помощью делегата incr.

А теперь обратите внимание на класс ThreeD. В этом классе инкапсулируются координаты трехмерного пространства (X,Z,Y). Его назначение — продемонстрировать обработку данных типа класса в классе ByTwos.

Далее в классе GenIntfDemo объявляются три метода увеличения на два для объектов типа int, double и ThreeD. Все эти методы передаются конструктору класса ByTwos при создании объектов соответствующих типов. Обратите особое внимание на приведенный ниже метод ThreeDPlusTwo().