Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Daniel Solis - Illustrated C# 2010 - 2010.pdf
Скачиваний:
16
Добавлен:
11.06.2015
Размер:
11.23 Mб
Скачать

CHAPTER 20 ENUMERATORS AND ITERATORS

Common Iterator Patterns

The previous two sections showed that you can create an iterator to return either an enumerable or an enumerator. Figure 20-11 summarizes how to use the common iterator patterns.

When you implement an iterator that returns an enumerator, you must make the class enumerable by implementing GetEnumerator so that it returns the enumerator returned by the iterator. This is shown on the left of the figure.

In a class, when you implement an iterator that returns an enumerable, you can either make this class itself enumerable or not by either making it implement GetEnumerator or not.

If you implement GetEnumerator, make it call the iterator method to get an instance of the automatically generated class that implements IEnumerable. Next, return the enumerator built by GetEnumerator from this IEnumerable object, as shown on the right of the figure.

If you don’t make the class itself enumerable by not implementing GetEnumerator, you can still use the enumerable returned by the iterator, by calling the iterator method directly, as shown in the second foreach statement on the right.

Figure 20-11. The common iterator patterns

530

CHAPTER 20 ENUMERATORS AND ITERATORS

Producing Enumerables and Enumerators

The previous examples used iterators that returned either an IEnumerator<T> or an IEnumerable<T>. You can also create iterators that return the nongeneric versions as well. The return types you can specify are the following:

IEnumerator<T> (generic—substitute an actual type for T)

IEnumerable<T> (generic—substitute an actual type for T)

IEnumerator (nongeneric)

IEnumerable (nongeneric)

For the two enumerator types, the compiler generates a nested class that contains the implementation of either the nongeneric or the generic enumerator, with the behavior specified by the iterator block.

For the two enumerable types, it does even more. It produces a nested class that is both enumerable and the enumerator. The class, therefore, implements both the enumerator interface and the GetEnumerator method. Notice that GetEnumerator is implemented as part of the nested class—not as part of the enclosing class.

531

CHAPTER 20 ENUMERATORS AND ITERATORS

Producing Multiple Enumerables

In the following example, class ColorCollection has two enumerable iterators—one enumerating the items in forward order and the other enumerating them in reverse order. Notice that although it has two methods that return enumerables, the class itself is not enumerable since it doesn’t implement GetEnumerator.

using

System;

 

using

System.Collections.Generic;

// You need this namespace.

namespace ColorCollectionIterator

{

class ColorCollection

{

string[] Colors={"Red", "Orange", "Yellow", "Green", "Blue", "Purple"};

public

IEnumerable<string> Forward() {

// Enumerable iterator

for

(int

i = 0; i < Colors.Length; i++)

 

}

yield

return Colors[i];

 

 

 

 

public

IEnumerable<string> Reverse() {

// Enumerable iterator

for

(int

i = Colors.Length - 1; i >= 0; i--)

}

yield

return Colors[i];

 

 

 

 

}

 

 

532

CHAPTER 20 ENUMERATORS AND ITERATORS

class Program

{

static void Main()

{

ColorCollection cc = new ColorCollection();

Return enumerable to the foreach statement

foreach (string color in cc.Forward()) Console.Write("{0} ", color);

Console.WriteLine();

Return enumerable to the foreach statement

foreach (string color in cc.Reverse()) Console.Write("{0} ", color);

Console.WriteLine();

// Skip the foreach and manually use the enumerable and enumerator. IEnumerable<string> ieable = cc.Reverse();

IEnumerator<string> ieator = ieable.GetEnumerator();

while (ieator.MoveNext()) Console.Write("{0} ", ieator.Current);

Console.WriteLine();

}

}

}

This code produces the following output:

Red Orange Yellow Green Blue Purple

Purple Blue Green Yellow Orange Red

Purple Blue Green Yellow Orange Red

533

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]