Практическая работа №13

Тема: «Клонирование. Итераторы»


Цель работы: Изучение принципов реализации перечислителей, итераторов при решении задач в C# .
Задачи:
· Изучить задачи и функции информационных систем;
· Ознакомиться особенности программных средств используемых в разработке информационных систем;
· Изучить методы и средства проектирования информационных систем
Формируемые компетенции: ПК 1.1., ОК 1-10.
Материально-техническое обеспечение: доска, учебники, сборник практических работ, комплект нормативных документов; классификация объектов технического регулирования, Общероссийский классификатор стандартов (ОКС), приложение 2-3.
Обеспечивающие средства: компьютеры, совместимые с IBM PC.

Ход работы:
1. Проверка готовности к ПР: опрос
2. Знакомство с теоретической частью
3. Выполнение заданий
4. Ответы на контрольные вопросы

Теоретическая часть

К элементам коллекции нередко приходится обращаться циклически, например, для отображения каждого элемента коллекции. С этой целью можно, с одной стороны, организовать цикл foreach, а с другой — воспользоваться перечислителем. Перечислитель — это объект, который реализует необобщенный интерфейс IEnumerator или обобщенный интерфейс IEnumerator<T>.
В интерфейсе IEnumerator определяется одно свойство, Current, необобщенная форма которого приведена ниже:
object Current { get; }
А в интерфейсе IEnumerator<T> объявляется следующая обобщенная форма свойства Current:
Т Current { get; }
В обеих формах свойства Current получается текущий перечисляемый элемент коллекции. Но поскольку свойство Current доступно только для чтения, то перечислитель может служить только для извлечения, но не видоизменения объектов в коллекции.
В интерфейсе IEnumerator определяются два метода. Первым из них является метод MoveNext(), объявляемый следующим образом:
boolMoveNext()
При каждом вызове метода MoveNext() текущее положение перечислителя смещается к следующему элементу коллекции. Этот метод возвращает логическое значение true, если следующий элемент коллекции доступен, и логическое значение false, если достигнут конец коллекции. Перед первым вызовом метода MoveNext() значение свойства Current оказывается неопределенным.
Для установки перечислителя в исходное положение, соответствующее началу коллекции, вызывается приведенный ниже метод Reset():
void Reset()
После вызова метода Reset() перечисление вновь начинается с самого начала коллекции. Поэтому, прежде чем получить первый элемент коллекции, следует вызвать метод MoveNext().
В интерфейсе IEnumerator<T> методы MoveNext() и Reset() действуют по тому же самому принципу. Необходимо также обратить внимание на два следующих момента. Во-первых, перечислитель нельзя использовать для изменения содержимого перечисляемой с его помощью коллекции. Следовательно, перечислители действуют по отношению к коллекции как к доступной только для чтения. И во-вторых, любое изменение в перечисляемой коллекции делает перечислитель недействительным.

Применение обычного перечислителя

Прежде чем получить доступ к коллекции с помощью перечислителя, необходимо получить его. В каждом классе коллекции для этой цели предоставляется метод GetEnumerator(), возвращающий перечислитель в начало коллекции. Используя этот перечислитель, можно получить доступ к любому элементу коллекции по очереди. В целом, для циклического обращения к содержимому коллекции с помощью перечислителя рекомендуется придерживаться приведенной ниже процедуры:
  • Получить перечислитель, устанавливаемый в начало коллекции, вызвав для этой коллекции метод GetEnumerator().
  • Организовать цикл, в котором вызывается метод MoveNext(). Повторять цикл до тех пор, пока метод MoveNext() возвращает логическое значение true.
  • Получить в цикле каждый элемент коллекции с помощью свойства Current.
ПРИМЕР:

Реализация интерфейсов IEnumerable и IEnumerator

Для циклического обращения к элементам коллекции зачастую проще организовать цикл foreach, чем пользоваться непосредственно методами интерфейса IEnumerator.
Интерфейс IEnumerable имеет метод, возвращающий ссылку на другой интерфейс - перечислитель:
public interface IEnumerable
{
IEnumerator GetEnumerator();
}
А интерфейс IEnumerator определяет функционал для перебора внутренних объектов в контейнере:
public interface IEnumerator
{
bool MoveNext(); // перемещение на одну позицию вперед в контейнере элементов
object Current {get;} // текущий элемент в контейнере
void Reset(); // перемещение в начало контейнера

Итераторы

Итератор представляет собой метод, оператор или аксессор, возвращающий по очереди члены совокупности объектов от ее начала и до конца. Так, если некоторый массив состоит из пяти элементов, то итератор данного массива возвратит все эти элементы по очереди. Реализовав итератор, можно обращаться к объектам определяемого пользователем класса в цикле foreach.
Обозначение yield служит в языке C# в качестве контекстного ключевого слова. Это означает, что оно имеет специальное назначение только в блоке итератора. А вне этого блока оно может быть использовано аналогично любому другому идентификатору. Следует особо подчеркнуть, что итератор не обязательно должен опираться на массив или коллекцию другого типа. Он должен просто возвращать следующий элемент из совокупности элементов. Это означает, что элементы могут быть построены динамически с помощью соответствующего алгоритма.
Для преждевременного прерывания итератора служит следующая форма оператора yield:
yield break;
Когда этот оператор выполняется, итератор уведомляет о том, что достигнут конец коллекции. А это, по существу, останавливает сам итератор. В итераторе допускается применение нескольких операторов yield. Но каждый такой оператор должен возвращать следующий элемент в коллекции.
Именованный итератор представляет собой метод, общая форма которого приведена ниже:
public IEnumerable имя_итератора(список_параметров) {
// ...
yield return obj;
}
где имя_итератора обозначает конкретное имя метода; список_параметров — от нуля до нескольких параметров, передаваемых методу итератора; obj — следующий объект, возвращаемый итератором. Как только именованный итератор будет создан, его можно использовать везде, где он требуется, например для управления циклом foreach.

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

Задание:
  1. Реализуйте примеры, приведенные в теоретической части
2. Решите задачи самостоятельно:
· Используя yield, реализовать и оттестировать метод-генератор n членов арифметической прогрессии с первым элементом a0 и шагом d. Для вывода реализовать метод Print, использующий yield и выводящий любую последовательность.
· Реализовать метод-генератор бесконечной последовательности значений val. Для тестирования реализовать метод IEnumerable<T> TakeN<T>(IEnumerable<T> seq, int n) который возвращает n первых членов бесконечной последовательности.
· Реализовать метод-генератор бесконечной последовательности случайных чисел.
· Реализовать метод-генератор бесконечной последовательности чисел Фибоначчи.
· Реализовать метод-генератор бесконечной последовательности циклически повторяющихся элементов последовательности seq
· Реализовать метод, принимающий две последовательности одинаковой длины и возвращающий последовательность пар в виде Tuple<T,T1>
· Реализовать метод, возвращающий по последовательности целых отфильтрованную последовательность, состоящую только из четных элементов исходной последовательности
· Реализовать метод, возвращающий по последовательности целых значений преобразованную последовательность квадратов этих значений.
· Реализовать метод, принимающий две последовательности элементов одного типа и возвращающий последовательность чередующихся элементов исходных последовательностей
· Реализовать метод, возвращающий по последовательности значений последовательность пар рядом стоящих значений:
1 2 3 4 5 -> (1,2) (2,3) (3,4) (4,5)


Технология выполнения задания
1.Прочитайте теоретическую часть.

2. Выполните задание.

This site was made on Tilda — a website builder that helps to create a website without any code
Create a website