Операторы языка C#
Специальные операторы
Операторы языка C#, рассмотренные выше, имеют аналоги практически во всех языках программирования. Поговорим теперь о более экзотических операторах, не столь часто появляющихся в других языках программирования.
Оператор yield
При рассмотрении оператора цикла foreach говорилось, что он применим к классам, содержащим контейнеры с элементами, и цикл foreach перебирает элементы контейнера в некотором заданном порядке. Для того чтобы класс представлял контейнер, он должен быть перечислимым и быть наследником интерфейса IEnumerable. Есть другая возможность - класс может иметь один или несколько методов, называемых итераторами, создающих контейнеры и возвращающих результат интерфейсного класса IEnumerable.
Оператор yield используется в итераторах и позволяет заполнять контейнер элементами. Его синтаксис:
yield return <выражение>;
Каждое выполнение оператора yield добавляет новый элемент в контейнер. Подробно рассмотрение этого оператора будет дано в главе, посвященной интерфейсам. Сейчас же ограничусь одним примером. В класс Testing, используемый в нашем проекте, добавим итератор, создающий коллекцию:
/// <summary> /// Итератор, создающий коллекцию цветов /// </summary> /// <returns>коллекцию </returns> public System.Collections.IEnumerable Rainbow() { yield return "red"; yield return "orange"; yield return "yellow"; yield return "green"; yield return "blue"; yield return "violet"; }
Клиенты этого класса могут работать с этой коллекцией, например, так:
string colors = ""; foreach(string s in tst.Rainbow()) colors += s + "-";
Здесь tst - объект класса Testing, а переменная s в цикле foreach получит значения всех цветов, помещенных в контейнер оператором yield. Следует заметить, что реально никакие контейнеры не создаются, а цикл foreach на каждом шаге вызывает итератор и создает новый элемент. Именно поэтому цикл foreach работает только на чтение элементов и не работает на запись.
Операторы try, catch, finally
Об охраняемых блоках, блоках, перехватывающих исключения, задаваемых операторами try, catch, finally, мы уже говорили в "Типы и классы. Переменные и объекты" и приводили достаточное число примеров. Тема организации обработки исключительных ситуаций и соответствующие операторы будут подробно рассматриваться в отдельной главе, а примеры их использования будут появляться повсеместно.
Операторы checked и unchecked
В "Выражения и операции" рассматривались проверяемые и непроверяемые выражения и блоки. Блоки с предшествующими словами checked и unchecked и являются соответствующими операторами. Полагаю, что приведенных ранее сведений достаточно для понимания синтаксиса, семантики и области применения этих операторов.
Оператор fixed
Оператор fixed используется в небезопасных ( unsafe ) блоках, позволяя фиксировать в памяти расположение переменных, на которые ссылаются указатели. Такая фиксация не позволяет сборщику мусора перемещать зафиксированные переменные. Поскольку в данном курсе работа с указателями, прямая адресация и другие опасные средства, характерные для языка С++, не рассматриваются, то оператор fixed рассматриваться не будет и не будет встречаться в примерах этого курса.
Оператор lock
Оператором lock, блоком lock, критической секцией кода, закрытым блоком называют блок с предшествующим ключевым словом lock
lock {…}
Этот оператор используется при работе с несколькими потоками. Он позволяет закрыть блок кода для одновременной работы нескольких потоков. Ни один поток не сможет войти в закрытый блок, если другой поток уже выполняет код критической секции. Остальные потоки будут ждать, пока закрытый блок не будет освобожден. Потокам будет посвящен отдельный раздел в этом курсе, где будет подробно рассмотрен и оператор lock.
Проект Statements
Как обычно, для этой главы построено решение с именем Ch4, содержащее Windows-проект с именем Statements. В проекте создан класс Testing, методы которого позволяют тестировать работу операторов языка C#. Эти методы используются в примерах, приведенных в этой главе. Архитектурно проект представляет Windows-приложение с главной кнопочной формой. Каждый из интерфейсных классов, включенных в проект, обеспечивает пользовательский интерфейс для работы с тем или иным методом класса Testing. На рис. 4.1 показаны формы проекта в процессе работы с ними.
Не буду приводить полного описания реализации этого проекта. Полагаю, что заинтересованный читатель сможет по рисунку и приведенным методам класса Testing самостоятельно построить аналог этого проекта.