Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Vse_shpory_po_OOP_polnye.doc
Скачиваний:
6
Добавлен:
20.09.2019
Размер:
295.94 Кб
Скачать

3. События. Объявление события. Шаблон проектирования события в классе. Свойство для безопасной работы с событиями. Безопасный вызов события в многопоточном программировании.

События генерируются, т.е. выдаются объектами, и для них можно предоставлять реагирующий на них выполнением какого-нибудь действия код. На события нужно подписываться. Под подпиской на событие подразумевается предоставление кода, который должен выполняться при генерации данного события, в виде обработчика событий. На событие можно подписывать несколько обработчиков, которые тогда все будут вызываться при генерации данного события. Эти обработчики могут являться как частью того класса объекта, который генерирует данное событие, так и частью других классов. Сами обработчики событий представляют собой просто функции. Единственным ограничением для такой функции является то, что ее возвращаемый тип и параметры должны обязательно соответствовать тем, которых требует событие. Это ограничение входит в состав определения события и задается делегатом. Базовая последовательность обработки выглядит следующим образом: сначала приложение создает объект, который может генерировать событие. Далее приложение подписывается на событие. Приложение может это делать путем определения функции, пригодной для использования с указанным в событии типом делегата, и передачи ссылки на эту функцию событию. Эта функция-обработчик событий может представлять собой метод в другом объекте. И, наконец, последнее: при генерации события подписчику отправляется соответствующее уведомление.

// Определение события

public event EventHandler<PlayEventArgs> PlayEvent;

События накладывают определенные правила на исполь­зование делегатов. Делегат должен что-нибудь возвращать и должен принимать два аргумента. Первый аргумент – ссылка на объект, представляющий сторо­ну, которая генерирует сообщение. Второй аргумент — тип, унаследованный от System.EventArgs. В С# пере­гружены операции + и -= для событий, чтобы предоставить компактную нота­цию для регистрации и отмены регистрации событий. Компиля­тор генерирует два метода— addOnPlay и removeOnPlay, которые вызываются, когда вы используете перегруженные операции += и -=. Эти методы управляют добавлением и удалением делегатов в цепочке делегатов событий. Фактически компилятор С# не позволяет вам вызывать эти методы явно, так что мы обязаны использовать перегруженные операции. Но есть способ контролировать тело этих двух функций. В С# необходимо проверить событие на равенство null, прежде чем вызывать его, иначе бу­дет сгенерировано исключение NullReferenceException. Метод OnPlay создает ло­кальную копию события перед проверкой на null. Это позволяет избежать состояния "гонок".

4. Обобщенные классы. Объявление и детализация класса типами пользователя.

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

List<int> list = new List<int>();

List<T> - объявление обобщенного класса (т.е. класс зависит от параметра);

Т - это указатель (место заполнения, куда подставляется любой тип - только после подставления конкретного типа получаем закрытый тип).

List<int> - процесс преобразования открытого типа в закрытый во время выполнения.

Закрытый тип используется как любой другой объявленный тип и следует тем же самыми правилам. Отличие состоит лишь в том, что он создан на основе обобщённого типа. Обобщения - удобный способ описания классов общего назначения с одинаковой логической функциональностью, но с жесткой типизацией параметров.

Механизм компиляции: В 2 этапа: 1) Компилятор из С#-кода (текста программы) генерирует промежуточный IL-код; этот код и будет находиться в скомпилированной программе. 2) происходит в момент загрузки программы и попытки выполнения участков кода (методов). Эту компиляцию осуществляет CLR и называется она JIT-компиляцией. Для каждого метода проводится только 1 раз. При ее выполнении самостоятельно выбирается оптимальный способ преобразования IL-конструкций в машинные инструкции. Обобщенные классы допускают перегрузку. Она выполняется только по числу параметров в обобщённом классе. На обобщённых классах допускается наследование.

Определение обобщенных классов. Для создания обобщенного класса достаточно применить в определении класса синтаксис в виде угловых скобок:

class MyGenericClass<T>

{ }

Здесь на месте Т можно указывать какой угодно идентификатор, главное соблюдать стандартные правила именования языка С#, т.е. не начинать имя с числа и т.п.

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

class MyGenericClass<Tl, Т2, Т3>

{ }

После определения эти типы можно применять в определении класса точно так же, как и любые другие типы. Например, их можно использовать и в качестве типов для переменных членов, и в качестве возвращаемых типов для членов, вроде свойств или методов, и в качестве типов параметров для аргументов методов. Другое ограничение, о котором тоже нужно знать, состоит в том, что при сравнении значения типа, указанного в обобщенном классе, со значением null, разрешено использовать только операцию == или !=.

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