|
Программирование >> Обработка исключительных ситуаций
Все, что требуется сделать в версии 2.0 для поддержки перебора, - указать, что класс реализует интерфейс lEnumerable (оператор 1), и описать итератор (оператор 2). Доступ к нему может быть осуществлен через методы MoveNext и Current интерфейса IEnumerator. За кодом, приведенным в листинге 9.5, стоит большая внутренняя работа компилятора. На каждом шаге цикла foreach для итератора создается оболочка - служебный объект, который запоминает текущее состояние итератора и выполняет все необходимое для доступа к просматриваемым элементам объекта. Иными словами, код, составляющий итератор, не выполняется так, как он выглядит - в виде непрерывной последовательности, а разбит на отдельные итерации, между которыми состояние итератора сохраняется. В листинге 9.6 приведен пример итератора, перебирающего четыре заданных строки. Листинг 9.6. Простейший итератор using System; using System.Collections; namespace ConsoleApplicationi class Nim : lEnumerable { public IEnumerator GetEnumerator() yield return one ; yield return two ; yield return three ; yield return oops ; class Classl { static void MainO foreach ( string s in new NumO ) Console.WriteLineC s ); Результат работы программы: one two three oops Следующий пример демонстрирует перебор значений в заданном диапазоне (от 1 до 5): using System; using System.Col lections; Параметры-ссылки Во многих методах все величины, которые метод должен получить в качестве исходных данных, описываются в списке параметров, а величина, которую вычисляет метод как результат своей работы, возвращается в вызывающий код с помощью оператора return. Очевидно, что если метод должен возвращать более одной величины, такой способ не годится. Еще одна проблема возникает, если в метоле О неявных преобразованиях рассказывалось в разделе Преобразования встроенных арифметических типов-значений (см. с. 45). О параметрах-массивах мы будем говорить позже, в главе 7 (см. с, 154), а сейчас рассмотрим остальные типы параметров. Параметры-значения Параметр-значение описывается в заголовке метода следующим образом: тип имя Пример заголовка метода, имеющего один параметр-значение целого типа: .oid Р( int х ) Имя параметра может быть произвольным. Параметр х представляет собой .локальную переменную, которая получает свое значение из вызывающей функции при вызове (метода. В метод передается копия значения аргумента. Механизм передачи следующий: из ячейки памяти, в которой хранится неременная, передаваемая в метод, берется ее значение и копируется в специальную область памяти - область параметров. Метод работает с этой копией, следовательно, доступа к ячейке, где хранится сама переменная, не имеет. По завершении работы метода область параметров освобождается. Таким образом, для параметров-значений используется, как вы догадались, передача но значению. Ясно, что этот способ годится только для величин, которые не должны измениться после выполнения метода, то есть для его исходных данных. При вызове метода на месте параметра, передаваемого по значению, может находиться выражение, а также, конечно, его частные случаи - переменная или константа. Должно существовать неявное преобразование типа выражения к типу параметра*. Например, пусть в вызывающей функции описаны переменные и им до вызова метода присвоены значения: -nt X = 1; ;;yte с = 1: .short у = 1: Тогда следующие вызовы метода Р, заголовок которого был описан ранее, будут синтаксически правильными: ; х ): Р( с ): Р( У ): Р( 200 ); Р( х / 4 + 1 ); namespace ConsoleApplicationi { class Classl { public static IEnumerable Count( int from, int to ) from = 1; while ( from <= to ) yield return from+ + : static void MainO foreach ( int i in Count( 1, 5 ) ) Console.WriteLineC i ); Преимущество использования итераторов заключается в том, что для одного и того же класса можно задать различный порядок перебора элементов. В листинге 9.7 описаны две дополнительные стратегии перебора элементов класса Stado, введенного в листинге 9.5, - перебор в обратном порядке и выборка только тех объектов, которые являются экземплярами класса Monster (для этого использован метод получения типа объекта GetType, унаследованный от базового класса object). Листинг 9.7. Реализация нескольких стратегий перебора using System; using System.Col lections; using MonsterLib: namespace ConsoleAppl icationi class Monster { . } class Daemon { ... } class Stado ; lEnumerable private Monster[] mas; private int n; public StadoO mas = new Monster[10]; n = 0; public IEnumerator GetEnumeratorO for ( int i =0; i < n; ++i ) yield return mas[i]; public lEnumerable BackwardsO в обратном порядке for ( int i = n - 1; i >= 0; -- i ) yield return mas[i]: public IEnumerable MonstersOnlyO только монстры
|
© 2006 - 2024 pmbk.ru. Генерация страницы: 0.001
При копировании материалов приветствуются ссылки. |