Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Методичка для КР по ООП.doc
Скачиваний:
8
Добавлен:
18.04.2019
Размер:
2.47 Mб
Скачать

События и делегаты. Различия

Так в чём же разница между событиями и делегатами в .NET?

В последнем примере предыдущего раздела при объявлении события очевидно его строгое соответствие определённому делегату.

public static event System.EventHandler xEvent;

System.EventHandler – это ТИП ДЕЛЕГАТА! Оператор, который обеспечивает процедуру “подписания на уведомление”, полностью соответствует оператору модификации многоадресного делегата. Аналогичным образом дело обстоит и с процедурой “отказа от уведомления”.

BaseClass.xEvent += new System.EventHandler(this.MyFun);

BaseClass.xEvent -= new System.EventHandler(xxx.MyFun);

И это действительно так. За операторными функциями += и -= скрываются методы классов-делегатов (в том числе и класса-делегата System.EventHandler).

Более того. Если в последнем примере в объявлении события ВЫКИНУТЬ ключевое слово event –

public static event System.EventHandler xEvent;

и заменить его на:

public static System.EventHandler xEvent;

System.EventHandler – это класс-делегат! То ничего не произойдёт. Вернее, ВСЁ будет происходить, как и раньше! Вместо пары СОБЫТИЕ-ДЕЛЕГАТ будет работать пара ДЕЛЕГАТ-ДЕЛЕГАТ. Таким образом, функционально событие является всего лишь разновидностью класса-делегата, главной задачей которого является обеспечение строгой привязки делегата к соответствующему событию.

Модификатор event вносит лишь незначительные синтаксические нюансы в использование этого МОДИФИЦИРОВАННОГО делегата. Чтобы хоть как-нибудь различать возбудителя и получателя события.

Атрибуты, сборки, рефлексия Рефлексия (отражение) типов

Процесс анализа типов (структуры типов) в ходе выполнения приложения (сборки). В .NET реализуется при помощи класса System.Type и пространства имён System.Reflection.

reflection - система, предоставляющая выполняемому коду информацию о нем самом.

Пространство имён System.Reflection содержит классы и интерфейсы, которые позволяют организовать просмотр загруженных в сборку типов, методов, полей (данных-членов), и обеспечивают динамические механизмы реализации типов и вызова методов. Включает множество взаимосвязанных классов, интерфейсов, структур и делегатов, предназначенных для реализации процесса отражения. Неполный перечень классов представлен ниже:

Тип

Назначение

Assembly

Методы для загрузки, описания и выполнения разнообразных операций над сборкой.

AssemblyName

Информация о сборке (идентификатор, версия, язык реализации).

EventInfo

Информация о событиях.

FieldInfo

Информация о полях.

MemberInfo

Абстрактный базовый класс, определяющий общие члены для EventInfo, FieldInfo, MethodInfo, PropertyInfo.

MethodInfo

Информация о методе.

Module

Позволяет обратиться к модулю в многофайловой сборке.

ParameterInfo

Информация о параметре.

PropertyInfo

Информация о свойстве.

Класс System.Type содержит методы, позволяющие получать информацию о типах приложения, пространства имён System.Reflection определяет типы для организации позднего связывания и динамической загрузки типов.

Класс Type является основой для реализации функциональности System.Reflection и средством для получения доступа к метаданным.

Использование членов класса Тип, позволяет получить информацию о:

  • типе (GetType(string)),

  • конструкторах (GetConstructors()),

  • методах (GetMethods()),

  • данных-членах (GetFields()),

  • свойствах (GetProperties()),

  • событиях, объявленных в классе (GetEvents()),

  • модуле,

  • сборке, в которой реализуется данный класс.

Объект-представитель класса Type уникален. Две ссылки на объекты-представители класса Type оказываются эквивалентными, если только они были построены в результате обращения к одному и тому же типу.

Объект-представитель класса Type может представить любой из следующих типов:

  • Классы

  • Размерные типы

  • Массивы

  • Интерфейсы

  • Указатели

  • Перечисления

Ссылка на объект-представитель класса Type, ассоциированная с некоторым типом, может быть получена одним из следующих способов:

1. В результате вызова метода

Type Object.GetType()

(метода-члена класса Object), который возвращает ссылку на объект-представитель типа Type, представляющий информацию о типе. Вызов производится от имени объекта-представителя данного типа. Вызов становится возможен в связи с тем, что любой класс наследует тип Object.

2. В результате вызова статического метода-члена класса Type:

public static Type Type.GetType(string)

Параметром является строка со значением имени типа. Возвращает объект-представитель класса Type, с информацией о типе, специфицированном параметром метода.

3. От имени объекта-представителя класса Assembly - от имени объекта-сборки (самоописываемого, многократно используемого, версифицируемого БЛОКА (фрагмента) CLR-приложения) вызываются методы

Type[] Assembly.GetTypes()

Type Assembly.GetType(string)

// Получаем ссылку на сборку, содержащую объявление типа MyType,

// затем – массив объектов-представителей класса Type.

Type[] tt = (Assembly.GetAssembly(typeof(MyType))).GetTypes();

// Без комментариев.

Type[] tt = (Assembly.GetAssembly(typeof(MyType))).GetType(“MyType”);

От имени объекта-представителя класса Module (Модуль - portable executable файл с расширением .dll или .exe, состоящий из одного и более классов и интерфейсов)

Type[] Module.GetTypes()

Type Module.GetType(string)

Type[] Module.FindTypes(TypeFilter filter, object filterCriteria)

где TypeFilter – класс-делегат

// The TypeFilter делегаты используются to filter списка классов.

// А как этим хозяйством пользоваться - не знаю. В хелпах не нашёл.

public delegate bool TypeFilter(Type m, object filterCriteria);

4. В результате выполнения операции typeof(), которая применяется для построения объекта-представителя класса System.Type. Выражение, построенное на основе операции typeof, имеет следующий вид:

typeof(type)

Операнд выражения – тип, для которого может быть построен объект-представитель класса System.Type.

Пример применения операции:

using System;

using System.Reflection;

public class MyClass

{

public int intI;

public void MyMeth()

{

}

public static void Main()

{

Type t = typeof(MyClass);

// Альтернативная эквивалентная конструкция

// MyClass t1 = new MyClass();

// Type t = t1.GetType();

MethodInfo[] x = t.GetMethods();

foreach (MethodInfo m in x)

{

Console.WriteLine(m.ToString());

}

Console.WriteLine();

MemberInfo[] x2 = t.GetMembers();

foreach (MemberInfo m in x2)

{

Console.WriteLine(m.ToString());

}

}

}