Читайте также:
|
|
// Определяем тип-делегат; экземпляры ссылаются на метод. // который принимает параметр типа Int32 и возвращает void internal delegate void Feedback(Int32 value);
В этом примере делегат задаст сигнатуру метода обратного вызова. Здесь Feedback определяет метод, принимающий один параметр типа Int32 и возвращающий void.
Класс Delegate является базовым для типов делегатов. Однако только система и компиляторы могут явно наследовать классы Delegate и MulticastDelegate. Также недопустимо создавать новые типы, производные от типа делегата. Класс Delegate не рассматривается как тип делегата, а является классом, наследуемым создаваемыми типами делегатов.
В большинстве языков программирования имеется ключевое слово delegate, и компиляторы этих языков способны создавать классы, производные от класса MulticastDelegate; поэтому пользователи должны использовать ключевое слово delegate, предоставляемое языком программирования.
Кроме наследуемых методов, среда CLR предоставляет два специальных метода для типов делегатов: BeginInvoke и EndInvoke.
Объявление типа делегата устанавливает контракт, определяющий сигнатуру одного или более методов. Делегат — это экземпляр типа делегата, содержащий указатели на:
метод экземпляра типа и целевой объект, который можно присваивать переменной этого типа;
метод экземпляра типа со скрытым параметром this, доступным в списке формальных параметров. Такой делегат называется открытым делегатом экземпляра;
статический метод;
статический метод и целевой объект, который можно присвоить первому параметру этого метода. Такой делегат называется закрытым в отношении своего первого аргумента.
Когда делегат представляет метод экземпляра, закрытый в отношении своего первого аргумента (наиболее типичный случай), этот делегат хранит ссылку на точку входа метода и ссылку на объект, называемый целевым, тип которого может присваиваться типу, определяемому методом. Когда delegate представляет открытый метод экземпляра, он содержит ссылку на точку входа этого метода. Сигнатура делегата должна содержать в списке формальных параметров скрытый параметр this; в таком случае делегат не содержит ссылку на целевой объект, и этот объект должен быть предоставлен при вызове делегата.
Когда делегат представляет статический метод, он содержит ссылку на точку входа этого метода. Когда делегат представляет метод экземпляра, закрытый в отношении своего первого аргумента, этот делегат содержит ссылку на точку входа метода и ссылку на целевой объект, который может присваиваться типу первого аргумента метода. При вызове делегата первый аргумент статического метода получает целевой объект.
Список вызовов делегата представляет собой упорядоченный набор элементов, каждый из которых в точности соответствует одному из методов, представленных делегатом. Список вызовов может содержать дублирующиеся методы. В процессе вызова методы вызываются в том порядке, в котором они находятся в списке вызовов. Делегат пытается вызвать все методы из своего списка вызовов; дубликаты вызываются по одному разу для каждого вхождения в списке вызовов. Делегаты являются неизменными, список вызовов делегата не меняется с момента его создания.
Делегаты называются групповыми или комбинируемыми, поскольку один делегат может вызывать один или более методов и использоваться в комбинирующих операциях.
Комбинирующие операции, такие как Combine и Remove, не изменяют существующие делегаты. Вместо этого такие операции возвращают новый делегат, содержащий результаты операции, неизмененный делегат или null. Комбинирующие операции возвращают null, когда результатом их выполнения является делегат, не ссылающийся хотя бы на один метод. Комбинирующие операции возвращают делегат без изменений, когда запрошенная операция не произвела никакого эффекта.
Если вызванный метод выбрасывает исключение, выполнение этого метода прекращается, исключение передается обратно коду, вызвавшему делегат, и оставшиеся в списке вызовов методы не вызываются. Перехват исключения в вызывающем коде не меняет этого поведения.
Когда сигнатура методов, вызываемых делегатом, включает возвращаемое значение, делегат возвращает значение, возвращенное последним элементом в списке вызовов. Когда сигнатура включает параметр, передаваемый по ссылке, конечным значением параметра является результат выполнения всех методов из списка вызовов, вызываемых последовательно и обновляющих значение этого параметра.
Все методы в среде.NET можно разделить на две группы: статические (static) и экземплярные (instance).
Если делегат ссылается на статический метод, то все действительно просто. Так как в этом случае есть вся необходимая для вызова метода информация: адрес метода и параметры. Если же делегат ссылается на экземплярный метод, то задача усложняется. Чтобы вызвать экземплярный метод, делегату необходимо знать ссылку на объект, к которому привязан данный конкретный метод. Оказывается, что эта ссылка хранится в самом объекте делегата и указывается при его создании. На протяжении всей жизни объекта делегата данная ссылка не изменяет своего значения, она всегда постоянна и может быть задана только при его создании. Таким образом, вне зависимости от того, ссылается ли делегат на статическую функцию или на экземплярный метод, обращение к нему извне ничем отличаться не будет. Всю необходимую функциональность обеспечивает сам делегат, вкупе со средой исполнения. Это очень удобно, поскольку множество разных делегатов можно привязывать к одному событию.
Дата добавления: 2015-01-30; просмотров: 62 | Поможем написать вашу работу | Нарушение авторских прав |