Коллекции и итераторы. Оператор yield — КиберПедия 

Поперечные профили набережных и береговой полосы: На городских территориях берегоукрепление проектируют с учетом технических и экономических требований, но особое значение придают эстетическим...

Индивидуальные очистные сооружения: К классу индивидуальных очистных сооружений относят сооружения, пропускная способность которых...

Коллекции и итераторы. Оператор yield

2017-11-27 276
Коллекции и итераторы. Оператор yield 0.00 из 5.00 0 оценок
Заказать работу

Для унификации работы с любыми контейнерами введено несколько интерфейсов и несколько классов. Стандартные конструкции С# часто опираются на эти интерфейсы и классы. При работе с коллекциями любого вида они предоставляют проход по всем элементам. Для того чтобы коллекцию можно было использовать в цикле foreach, класс коллекций должен реализовывать интерфейс IEnumerable //перечисление, IEnumerable<T>.

У них есть метод GetEnumerator().

IEnumerator – базовый класс итератора. Именно итератор обычно передается в тех случаях, когда нужно проходить коллекцию. Итератор — это раздел кода, возвращающий упорядоченную последовательность значений одинакового типа. Итератор может использоваться в качестве основной части метода, оператора или метода доступа get. Объект итератора, начиная с С# 3.0, строится определенным образом. Он не создается с помощью оператора new явно. Пример «Обертка для коллекции»:

List<T>

public class StringListWrapper: IEnumerable <string>

{

private List<string> data = new List <string>();

public IEnumerator <string>GetEnumerator()

{ return data.GetEnumerator (); }

}

Если исходный класс не поддерживает интерфейс IEnumerable, тогда итератор придется построить. Это можно сделать 2-мя способами: 1. определить класс итератора путем реализации интерфейса IEnumerator. Это имеет смысл только в С# 2.0. Итератор как интерфейс имеет несколько методов: установки начального элемента и продвижение к следующему элементу, и признак завершения. 2. определение итератора на ходу:

public class StringListWrapper: IEnumerable <string>

{

private List<string> data = new List <string>();

public IEnumerator <string>GetEnumerator()

{

int i = 0;

while (i < data.Count)

{yield return data [ i ];

i++; }

}

}

yield – строит объект итератора, затем возвращает ссылку на основной элемент.

При вызове метода GetEnumerator компилятор выполняет ряд хитростей: 1) компилятор способен распознать, какие типы данных будут содержаться в объекте итератора; 2) компилятор конструирует объект анонимного типа и размещает в нем все необходимые поля данных; 3) эти поля данных в объекте итератора инициализируются.

 

IEnumerator<T>

{

void Reset (); // позволяет сбрасывать итератор в исходное состояние

bool MoveNext (); // позволяет переходить к след. элементу – передвигать итератор

T Current { get; }

}

Компилятор ищет блок yield и на его основе формирует метод MoveNext. При каждом выполнении строки
«yield return data [i];» наверх передается объект коллекции. Но ход выполнения цикла не прерывается, а останавливается с выходом из метода. При последовательном вызове метода MoveNext выполнение цикла продолжается со следующего оператора, т.е. оператора i++.

Существуют способы построения обратных и двунаправленныхитераторов. Итераторы можно снабжать дополнительными методами для управления. При конструировании классов итераторов и коллекций следуют следующему правилу: не следует делать так, чтобы один и тот же класс одновременно реализовывал оба интерфейса: IEnumerable<T>, IEnumerator<T>. Нельзя, чтобы один и тот же класс был и коллекцией, и итератором. При передаче коллекции в качестве параметра метода вследствие того, что параметры надо передавать как можно в более общем виде, часто передают не сами объекты коллекции, а итераторы или интерфейсы, которые реализуются классами коллекций. Всё зависит от того, какую функциональность коллекций собирается использовать метод. Если нужен только проход по коллекции, то используют IEnumerable<T>.

Более развитый интерфейс ICollection<T>. Он наследуется от IEnumerable<T>. Он дает дополнительные методы для вставки и удаления объекта, очистки коллекции, проверки принадлежности элемента коллекции.

Ещё более развитый интерфейс IList<T>: ICollection<T>. Он дает все операции по индексу ICollection.

Отдельное положение занимает интерфейс IDictionary<TKey, TValue>: IEnumerable. Он повторяет в себе методы ICollection + операции поиска по ключу, удаления.

Для сортированных коллекций используется интерфейс IComparer<T>.

У него есть единственный метод:

int Comparer(T a, T b) – возвращает целое значение (> 0 если a < b; 0, если a == b; < 0, если a > b).


 


Поделиться с друзьями:

Историки об Елизавете Петровне: Елизавета попала между двумя встречными культурными течениями, воспитывалась среди новых европейских веяний и преданий...

Индивидуальные и групповые автопоилки: для животных. Схемы и конструкции...

Двойное оплодотворение у цветковых растений: Оплодотворение - это процесс слияния мужской и женской половых клеток с образованием зиготы...

Адаптации растений и животных к жизни в горах: Большое значение для жизни организмов в горах имеют степень расчленения, крутизна и экспозиционные различия склонов...



© cyberpedia.su 2017-2024 - Не является автором материалов. Исключительное право сохранено за автором текста.
Если вы не хотите, чтобы данный материал был у нас на сайте, перейдите по ссылке: Нарушение авторских прав. Мы поможем в написании вашей работы!

0.007 с.