Итераторы в C#

Лекции по предмету «Программирование»
Информация о работе
  • Тема: Итераторы в C#
  • Количество скачиваний: 15
  • Тип: Лекции
  • Предмет: Программирование
  • Количество страниц: 3
  • Язык работы: Русский язык
  • Дата загрузки: 2015-01-04 00:09:14
  • Размер файла: 20.15 кб
Помогла работа? Поделись ссылкой
Информация о документе

Документ предоставляется как есть, мы не несем ответственности, за правильность представленной в нём информации. Используя информацию для подготовки своей работы необходимо помнить, что текст работы может быть устаревшим, работа может не пройти проверку на заимствования.

Если Вы являетесь автором текста представленного на данной странице и не хотите чтобы он был размешён на нашем сайте напишите об этом перейдя по ссылке: «Правообладателям»

Можно ли скачать документ с работой

Да, скачать документ можно бесплатно, без регистрации перейдя по ссылке:

Итераторы в C#

Для обращения к элементам списка можно реализовать интерфейсы IEnumerator и IEnumerable. В последних версиях Visual Studio эти интерфейсы, часто, реализуются автоматически компилятором. Но можно использовать итератор, который представляет собой метод, оператор или аксессор, возвращающий по очереди члены совокупности объектов от ее начала и до конца. Отличие итератора от индекса заключается в том, что итератор не связан с типом списка и позволяет обращаться к элементам связного списка так же, как и к элементам обычного массива. Более того, при создании коллекций с применением итераторов вся коллекция сразу не создается, формируется только текущий элемент.
вставка
У итераторов есть встроенные машины состояний. Используя новое ключевое слово yield, ваша программа может возвращать значения в оператор foreach, вызвавший итератор. В следующий раз, когда снова вызывает итератор, он начинает выполнение с того места, на котором остановился предыдущий оператор yield. В следующем примере ваша программа итерирует по трем строковыым типам:
public class List// Не работает
{
internal object[] elements;
internal int count;

public string foreach()
{
yield "microsoft";
yield "corporation";
yield "developer division";
}
}
В следующем примере цикл foreach, который вызывает этот итератор, будет выполнен три раза, каждый раз получая строки в порядке, определенном тремя предыдущими операторами yield:
List list = new List();
foreach(string s in list)
{
Console.WriteLine(s);
}
Если вы хотите, чтобы программа реализовывала итератор для прохода элементов списка, вы должны модифицировать итератор так, чтобы он проходил через массив элементов, используя цикл foreach, возвращая каждый элемент массива в каждой итерации:
public class List
{
internal object[] elements;
internal int count;

public object foreach()
{
foreach(object o in elements)
{
yield o;
}
}
}
Как работают итераторы
Итератором является метод, который формирует перечисляемые последовательности, используя специальное ключевое слово yield. В примере ниже показан класс, в котором реализован итератор. Выводятся числа нечетные числа от 1 до 11.
class MyClass
{
int last = 0;
public MyClass(int last) { this.last = last; }

public IEnumerable<int> NumColl(int beg)
{
for (int i = beg; i <= last; i++)
yield return 2 * i + 1;
}
}
class Program
{
static void Main(string[ ] args)
{
MyClass mc = new MyClass(5);
foreach (int i in mc. NumColl(0))
Console.Write("{0} ", i);
Console.ReadKey();
}
}
Вывод программы

Итератор похож на обычный метод, но различен способ возврата значения. Итератор в примере имеет код возврата IEnumerable<int>, и не видно, чтобы он что-либо возвращал этого типа. Он не содержит обычного оператора возврата, и содержит только оператор yield return, но он возвращает одиночное число типа int, а не коллекцию. Итераторы формируют значения по одному за раз с помощью оператора yield return, и в отличие от обычного возврата метод продолжает выполняться, пока либо достигнет конца, либо будет остановлен преждевременно с помощью оператора yield break, либо возникнет исключительная операция. Каждый оператор формирует значение, которое вставляется в последовательность. В следующем примере это показано более четко, где формируются числа 1 ÷ 3.
Очень простой итератор
public static IEnumerable<int> ThreeNumbers()
{
yield return 1;
yield return 2;
yield return 3;
}
Хотя это простая концепция, способ реализации в чем-то отличен, поскольку итераторы не выполняются таким же способом, как и другой код. Напомним, что с помощью IEnumerable<T> вызывающая программа занята при извлечении следующего значения. Цикл foreach получает перечислитель и повторяет вызов метода MoveNext() до тех пор, пока не будет возвращено значение false и не будет обращения к свойству Current для получения текущего значения. Однако значения перечислителя не хранятся в списке типа List<T>
Ниже приведен простой пример итератора, в котором вместо явной реализации интерфейсов IEnumerator и IEnumerable применяется итератор.
// Простой пример применения итератора.
class MyClass
{
string[ ] strs = { "Anchor", "Broadcast", "City", "Danger" };
// Этот итератор возвращает строки из массива strs в классе MyClass.
public IEnumerator<string> GetEnumerator()
{
foreach (string st in strs)
yield return st;
}
}
class Iterator
{
static void Main()
{
MyClass mc = new MyClass();
foreach (string st in mc) Console.WriteLine(st + " ");
Console.ReadKey();
}
}
При выполнении этой программы получается следующий результат.

Как видите, выполнено последовательное обращение к элементам массива strs в объекте mc класса MyClass.
Рассмотрим эту программу более подробно. Во-первых, обратите внимание на то, что в классе MyClass не указывается IEnumerator в качестве реализуемого интерфейса. При создании итератора компилятор реализует этот интерфейс автоматически. И, во-вторых, обратите особое внимание на метод GetEnumerator (), который ради удобства приводится ниже еще раз.