Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
30-36.docx
Скачиваний:
1
Добавлен:
25.09.2019
Размер:
40.51 Кб
Скачать

34. События. Безымянные методы.

Назначение безымянных методов (anonymous methods) – сократить объем кода, который должен написать разработчик при работе с событиями. Рассмотрим пример, в котором назначаются обработчики событий для объектов класса CExampleClass (подробнее – в параграфе, посвященном работе с событиями).

class MainClass {

public static void firstReaction(int i) {

Console.WriteLine("{0} is a bad value!", i);

}

public static void secondReaction(int i) {

Console.WriteLine("Are you stupid?");

}

public static void Main() {

CExampleClass c = new CExampleClass();

// Назначаем обработчик

c.onErrorEvent += new Proc(firstReaction);

// Назначаем еще один обработчик

c.onErrorEvent += new Proc(secondReaction);

}

}

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

class MainClass {

public static void Main() {

CExampleClass c = new CExampleClass();

// Назначаем обработчик

c.onErrorEvent += delegate(int i) {

Console.WriteLine("{0} is a bad value!", i); };

// Назначаем еще один обработчик

c.onErrorEvent += delegate {

Console.WriteLine("Are you stupid?"); };

}

}

Таким образом, код обработки события помещен непосредственно в место присваивания делегата событию onErrorEvent. Теперь компилятор сам создаст делегат, основываясь на указанной сигнатуре анонимного метода, поместит в этот делегат указатель на код анонимного метода, а сам объект делегата присвоит событию.

Обратите внимание в предыдущем фрагменте кода на второй безымянный метод. Он не использовал параметр события, что позволило не указывать сигнатуру метода после delegate. Компилятор автоматически выполняет соответствующие неявные преобразования для делегатов и безымянных методов. Точные правила совместимости делегата и безымянного метода выглядят следующим образом:

1. Список параметров делегата совместим с безымянным методом, если выполняется одно из двух условий:

a. безымянный метод не имеет параметров, а делегат не имеет out-параметров;

b. список параметров безымянного метода полностью совпадает со списком параметров делегата (число параметров, типы, модификаторы)

2. Тип, возвращаемый делегатом, совместим с типом безымянного метода, если выполняется одно из двух условий:

a. тип делегата – void, а безымянный метод не имеет оператора return или оператор return записан без последующего выражения;

b. выражение, записанное после return в безымянном методе, может быть неявно приведено к типу делегата.

35. Обработка исключений.

Опишем возможности по обработке исключительных ситуаций. Для перехвата исключительных ситуаций служит блок try – catch – finally. Синтаксис блока следующий:

try {

[<команды, способные вызвать исключительную ситуацию>]

}

[<один или несколько блоков catch>]

[finally {

<операторы из секции завершения> }]

Операторы из части finally (если она присутствует) выполняются всегда, вне зависимости от того, произошла исключительная ситуация или нет. Если один из операторов, расположенных в блоке try, вызвал исключительную ситуацию, управление немедленно передается на блоки catch. Синтаксис отдельного блока catch следующий:

catch [(<тип ИС> [<идентификатор объекта ИС>])] {

<команды обработки исключительной ситуации>

}

<идентификатор объекта ИС> – это некая временная переменная, которая может использоваться для извлечения информации из объекта исключительной ситуации. Отдельно описывать эту переменную нет необходимости.

Программа с добавленным в нее блок перехвата ошибки:

class MainClass

{

public static void Main()

{

CExample A = new CExample();

try {

Console.WriteLine("Эта строка печатается");

A.setFx(-3);

Console.WriteLine("Строка не печатается, если ошибка ");

}

catch (MyException ex) {

Console.WriteLine("Ошибка при параметре {0}", ex.Info);

}

finally {

Console.WriteLine("Строка печатается - блок finally");

}

}

}

Если используется несколько блоков catch, то обработка исключительных ситуаций должна вестись по принципу «от частного – к общему», так как после выполнения одного блока catch управление передается на часть finally (при отсутствии finally – на оператор после try – catch). Компилятор C# не позволяет разместить блоки catch так, чтобы предыдущий блок перехватывал исключительные ситуации, предназначенные последующим блокам.

Соседние файлы в предмете [НЕСОРТИРОВАННОЕ]