Студопедия — Foreach
Студопедия Главная Случайная страница Обратная связь

Разделы: Автомобили Астрономия Биология География Дом и сад Другие языки Другое Информатика История Культура Литература Логика Математика Медицина Металлургия Механика Образование Охрана труда Педагогика Политика Право Психология Религия Риторика Социология Спорт Строительство Технология Туризм Физика Философия Финансы Химия Черчение Экология Экономика Электроника

Foreach






Оператор foreach осуществляет перечисление элементов коллекции, выполняя внедренный оператор для каждого элемента коллекции.

оператор_foreach:
foreach (тип_локальной_переменной идентификатор in выражение) встроенный_оператор

Тип и идентификатор в каждом операторе foreach объявляют итерационную переменную оператора. Если тип_локальной_переменной задан идентификатором var, и в области видимости не существует типа именованного var, говорят, что это неявно введенная итерационная переменная, и в качестве ее типа принимается тип элементов оператора foreach, как описано ниже. Итерационная переменная соответствует локальной переменной, доступной только на чтение, область видимости которой охватывает внедренный оператор. В ходе выполнения оператора foreach итерационная переменная представляет элемент коллекции, для которого в данный момент выполняется итерация. Если внедренный оператор пытается изменить итерационную переменную (путем присваивания или с помощью операторов ++ и ‑‑) или передать ее как параметр ref или out, возникает ошибка времени компиляции.

Во время компиляции оператора foreach сначала определяется тип коллекции;, тип перечислителя; и тип элементов; для выражения. Это происходит следующим образом.

· Если типом X выражения является тип массива, производится неявное преобразование ссылочного типа X в интерфейс System.Collections.IEnumerable (поскольку System.Array реализует этот интерфейс). В качестве типа коллекции принимается интерфейс System.Collections.IEnumerable, в качестве типа перечислителя — интерфейс System.Collections.IEnumerator, и в качестве типа элементов — тип элементов массива типа X.

· Если тип X выражения; имеет вид dynamic, существует неявное преобразование типа из выражения; в интерфейс System.Collections.IEnumerable (§6.1.8). В качестве типа коллекции принимается интерфейс System.Collections.IEnumerable, в качестве типа перечислителя — интерфейс System.Collections.IEnumerator. Если идентификатор var представлен как тип_локальной_переменной;, то типом элемента будет dynamic, в противном случае – object.

· В противном случае следует определить, существует ли для типа X соответствующий метод GetEnumerator.

o Выполняется поиск членов для типа X с идентификатором GetEnumerator без использования аргументов типа. Если поиск членов не дает результата, или дает неоднозначный результат, или находит член, не являющийся группой методов, следует проверить наличие перечислимого интерфейса, как описано ниже. Рекомендуется выдавать предупреждение, если результатом поиска членов является что-либо, кроме группы методов или отсутствия совпадений.

o Выполняется разрешение перегрузки с использованием результирующей группы методов и пустого списка аргументов. Если разрешение перегрузки не позволяет получить применимые методы, дает неоднозначный результат или приводит к единственному наилучшему методу, который описан как статический или не открытый, следует проверить наличие перечислимого интерфейса, как описано ниже. Рекомендуется выдавать предупреждение, если результатом разрешения перегрузки является что-либо, кроме однозначно определенного открытого метода экземпляра или отсутствия применимых методов.

o Если тип возвращаемого значения E метода GetEnumerator не является типом класса, структуры или интерфейса, возникает ошибка, и больше никакие действия не выполняются.

o Выполняется поиск членов для типа E с идентификатором Current без использования аргументов типа. Если поиск членов не дает результата, приводит к ошибке или находит что-либо, кроме открытого свойства экземпляра, разрешающего чтение, возникает ошибка, и больше никакие действия не выполняются.

o Выполняется поиск членов для типа E с идентификатором MoveNext без использования аргументов типа. Если поиск членов не дает результата, приводит к ошибке или находит что-либо, кроме группы методов, возникает ошибка, и больше никакие действия не выполняются.

o Выполняется разрешение перегрузки для группы методов с использованием пустого списка аргументов. Если разрешение перегрузки не позволяет получить применимые методы, дает неоднозначный результат или приводит к единственному наилучшему методу, который описан как статический или не открытый либо возвращает значение типа, отличного от bool, возникает ошибка, и больше никакие действия не выполняются.

o В качестве типа коллекции принимается X, в качестве типа перечислителя — E, в качестве типа элементов — тип свойства Current.

· В противном случае проверяется наличие перечислимого интерфейса.

o Если имеется ровно один тип T, для которого существует неявное преобразование типа X в интерфейс System.Collections.Generic.IEnumerable<T>, то в качестве типа коллекции принимается этот интерфейс, в качестве типа перечислителя — интерфейс System.Collections.Generic.IEnumerator<T>, и в качестве типа элементов — T.

o Если таких типов T несколько, возникает ошибка, и больше никакие действия не выполняются.

o Если существует неявное преобразование типа X в интерфейс System.Collections.IEnumerable, в качестве типа коллекции принимается этот интерфейс, в качестве типа перечислителя — интерфейс System.Collections.IEnumerator, и в качестве типа элементов — object.

o В противном случае возникает ошибка, и больше никакие действия не выполняются.

Если описанная выше процедура завершается успешно, она дает однозначно определенный результат: тип коллекции C, тип перечислителя E и тип элементов T. После этого оператор foreach, заданный в виде

foreach (V v in x) внедренный_оператор

развертывается следующим образом:

{
E e = ((C)(x)).GetEnumerator();
try {
V v;
while (e.MoveNext()) {
v = (V)(T)e.Current;
внедренный_оператор
}
}
finally {
… // Dispose e
}
}

Переменная e невидима и недоступна для выражения x, внедренного оператора и любого другого исходного кода программы. Переменная v доступна только для чтения во внедренном операторе. Если не определено явное преобразование (§6.2) типа T (типа элементов) в V (тип_локальной_переменной; в операторе foreach), возникает ошибка, и больше никакие действия не выполняются. Если x имеет значение null, во время выполнения генерируется исключение System.NullReferenceException.

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

Тело блока finally строится по следующим правилам.

· Если существует неявное преобразование E в интерфейс System.IDisposable, то

o Если E является необнуляемым типом значений, предложение finally развертывается в семантический эквивалент следующего:

finally {
((System.IDisposable)e).Dispose();
}

o В противном случае предложение finally развертывается в семантический эквивалент следующего:

finally {
if (e!= null) ((System.IDisposable)e).Dispose();
}

Исключение составляют ситуации, когда E является типом значения, или же параметром типа, экземпляром которого оказывается тип значения; в этих случаях приведение e к System.IDisposable не сопровождается упаковкой.

· Если E является запечатанным типом, предложение finally развертывается в пустой блок:

finally {
}

· В противном случае предложение finally развертывается следующим образом:

finally {
System.IDisposable d = e as System.IDisposable;
if (d!= null) d.Dispose();
}

Локальная переменная d невидима или недоступна для любого пользовательского кода. В частности, она не вступает в конфликты с другими переменными, чьи области видимости включают блок finally.

Оператор foreach обходит элементы массива в следующем порядке. Элементы одномерных массивов обходятся в порядке возрастания индекса, начиная с индекса 0 и заканчивая индексом Length – 1. Элементы многомерных массивов обходятся сначала по возрастанию индексов самого правого измерения, затем по возрастанию индексов следующего измерения слева и так далее до самого левого измерения.

В следующем примере выводится каждое значение двумерного массива в порядке следования элементов:

using System;

class Test
{
static void Main() {
double[,] values = {
{1.2, 2.3, 3.4, 4.5},
{5.6, 6.7, 7.8, 8.9}
};

foreach (double elementValue in values)
Console.Write("{0} ", elementValue);

Console.WriteLine();
}
}

Вывод выглядит следующим образом:

1.2 2.3 3.4 4.5 5.6 6.7 7.8 8.9

В этом примере

int[] numbers = { 1, 3, 5, 7, 9 };
foreach (var n in numbers) Console.WriteLine(n);

в качестве типа n неявно принимается int — тип элементов массива numbers.

8.9 Операторы перехода;

Операторы перехода осуществляют безусловную передачу управления.

оператор_перехода:
оператор_break
оператор_continue
оператор_goto
оператор_return
оператор_throw

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

Если оператор перехода находится внутри блока, а его цель — вне этого блока, говорят, что оператор перехода производит выход из блока. Оператор перехода может передавать управление за пределы блока, но он никогда не передает управление внутрь блока.

Выполнение оператора перехода усложняется при наличии сопутствующих операторов try. В отсутствие таких операторов try оператор перехода выполняет безусловную передачу управления своей цели. При его использовании вместе с операторами try схема выполнения становится более сложной. Если оператор перехода производит выход из одного или нескольких блоков try, с которыми связаны соответствующие блоки finally, управление вначале передается в блок finally самого внутреннего оператора try. Если управление достигает конечной точки блока finally, после этого управление передается в блок finally следующего объемлющего оператора try. Этот процесс повторяется до тех пор, пока не будут выполнены все блоки finally всех сопутствующих операторов try.

В этом примере

using System;

class Test
{
static void Main() {
while (true) {
try {
try {
Console.WriteLine("Before break");
break;
}
finally {
Console.WriteLine("Innermost finally block");
}
}
finally {
Console.WriteLine("Outermost finally block");
}
}
Console.WriteLine("After break");
}
}

перед передачей управления в цель оператора перехода выполняются блоки finally, соответствующие двум операторам try.

Вывод выглядит следующим образом:

Before break
Innermost finally block
Outermost finally block
After break

Break

Оператор break осуществляет выход из ближайшего объемлющего оператора switch, while, do, for или foreach.

оператор_break:
break;

Целью оператора break является конечная точка ближайшего объемлющего оператора switch, while, do, for или foreach. Если оператор break не содержится ни в каком операторе switch, while, do, for или foreach, возникает ошибка времени компиляции.

Если несколько операторов switch, while, do, for или foreach вложены друг в друга, оператор break применяется только к самому внутреннему из них. Для передачи управления с переходом через несколько уровней вложенности следует использовать оператор goto (§8.9.3).

Оператор break не дает возможности выйти из блока finally (§8.10). Если оператор break встречается внутри блока finally, цель оператора break должна находиться в том же блоке finally, в противном случае возникнет ошибка времени компиляции.

Оператор break выполняется следующим образом.

· Если оператор break производит выход из одного или нескольких блоков try, с которыми связаны соответствующие блоки finally, управление вначале передается в блок finally самого внутреннего оператора try. Если управление достигает конечной точки блока finally, после этого управление передается в блок finally следующего объемлющего оператора try. Этот процесс повторяется до тех пор, пока не будут выполнены все блоки finally всех сопутствующих операторов try.

· Управление передается цели оператора break.

Поскольку оператор break осуществляет безусловную передачу управления в другое место, конечная точка оператора break никогда не будет достижима.







Дата добавления: 2015-09-07; просмотров: 448. Нарушение авторских прав; Мы поможем в написании вашей работы!



Обзор компонентов Multisim Компоненты – это основа любой схемы, это все элементы, из которых она состоит. Multisim оперирует с двумя категориями...

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

Важнейшие способы обработки и анализа рядов динамики Не во всех случаях эмпирические данные рядов динамики позволяют определить тенденцию изменения явления во времени...

ТЕОРЕТИЧЕСКАЯ МЕХАНИКА Статика является частью теоретической механики, изучающей условия, при ко­торых тело находится под действием заданной системы сил...

Концептуальные модели труда учителя В отечественной литературе существует несколько подходов к пониманию профессиональной деятельности учителя, которые, дополняя друг друга, расширяют психологическое представление об эффективности профессионального труда учителя...

Конституционно-правовые нормы, их особенности и виды Характеристика отрасли права немыслима без уяснения особенностей составляющих ее норм...

Толкование Конституции Российской Федерации: виды, способы, юридическое значение Толкование права – это специальный вид юридической деятельности по раскрытию смыслового содержания правовых норм, необходимый в процессе как законотворчества, так и реализации права...

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

Неисправности автосцепки, с которыми запрещается постановка вагонов в поезд. Причины саморасцепов ЗАПРЕЩАЕТСЯ: постановка в поезда и следование в них вагонов, у которых автосцепное устройство имеет хотя бы одну из следующих неисправностей: - трещину в корпусе автосцепки, излом деталей механизма...

Понятие метода в психологии. Классификация методов психологии и их характеристика Метод – это путь, способ познания, посредством которого познается предмет науки (С...

Studopedia.info - Студопедия - 2014-2024 год . (0.012 сек.) русская версия | украинская версия