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

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

<b>    MyClass mc = new MyClass();</b>

<b>    Console.WriteLine(&quot;Возвратить по очереди первые 7 букв:&quot;);</b>

<b>    foreach (char ch in mc.MyItr(7))</b>

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

<b>    Console.WriteLine(&quot;n&quot;);</b>

<b>    Console.WriteLine(&quot;Возвратить по очереди буквы от F до L:&quot;);</b>

<b>    foreach (char ch in mc.MyItr(5, 12))</b>

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

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

<b>  }</b>

<b>}</b>

Эта программа дает следующий результат.

<b>Возвратить по очереди первые 7 букв:</b>

<b>А В С D Е F G</b>

<b>Возвратить по очереди буквы от F до L:</b>

<b>F G Н I J К L</b>

В приведенных выше примерах применялись необобщенные итераторы, но, конечно, ничто не мешает создать обобщенные итераторы. Для этого достаточно возвратить объект обобщенного типа IEnumerator&lt;T&gt; или IEnumerable&lt;T&gt;. Ниже приведен пример создания обобщенного итератора.

<b>// Простой пример обобщенного итератора,</b>

<b>using System;</b>

<b>using System.Collections.Generic;</b>

<b>class MyClass&lt;T&gt; {</b>

<b>  T[] array;</b>

<b>  public MyClass(T[] a) {</b>

<b>    array = a;</b>

<b>  }</b>

<b>  // Этот итератор возвращает символы из массива chrs.</b>

<b>  public IEnumerator&lt;T&gt; GetEnumerator() {</b>

<b>    foreach (T obj in array)</b>

<b>      yield return obj;</b>

<b>  }</b>

<b>}</b>

<b>class GenericItrDemo {</b>

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

<b>    int[] nums = { 4, 3, 6, 4, 7, 9 };</b>

<b>    MyClass&lt;int&gt; mc = new MyClass&lt;int&gt;(nums);</b>

<b>    foreach (int x in mc)</b>

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

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

<b>    bool[] bVals = { true, true, false, true };</b>

<b>    MyClass&lt;bool&gt; mc2 = new MyClass&lt;bool&gt;(bVals);</b>

<b>    foreach (bool b in mc2)</b>

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

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

<b>  }</b>

<b>}</b>

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

<b>4 3 6 4 7 9</b>

<b>True True False True</b>

В данном примере массив, состоящий из возвращаемых по очереди объектов, передается конструктору класса MyClass. Тип этого массива указывает в качестве аргумента типа в конструкторе класса MyClass.

Метод GetEnumerator() оперирует данными обобщенного типа Т и возвращает перечислитель типа IEnumerator&lt;T&gt;. Следовательно, итератор, определенный в классе MyClass, способен перечислять данные любого типа.

Инициализаторы коллекций

В С# имеется специальное средство, называемое инициализатором коллекции и упрощающее инициализацию некоторых коллекций. Вместо того чтобы явно вызывать метод Add(), при создании коллекции можно указать список инициализаторов. После этого компилятор организует автоматические вызовы метода Add(), используя значения из этого списка. Синтаксис в данном случае ничем не отличается от инициализации массива. Обратимся к следующему примеру, в котором создается коллекция типа List&lt;char&gt;, инициализируемая символами С, А, Е, В, D и F.

<b>List&lt;char&gt; lst = new List&lt;char&gt;() { 'С', 'А', 'Е', 'В', 'D', 'F' };</b>

После выполнения этого оператора значение свойства lst.Count будет равно 6, поскольку именно таково число инициализаторов. А после выполнения следующего цикла foreach:

<b>foreach(ch in lst)</b>

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

получится такой результат:

<b>С A E В D F</b>

Для инициализации коллекции типа LinkedList&lt;TKey, TValue&gt;, в которой хранятся пары "ключ-значение", инициализаторы приходится предоставлять парами, как показано ниже.