Студопедия

КАТЕГОРИИ:


Архитектура-(3434)Астрономия-(809)Биология-(7483)Биотехнологии-(1457)Военное дело-(14632)Высокие технологии-(1363)География-(913)Геология-(1438)Государство-(451)Демография-(1065)Дом-(47672)Журналистика и СМИ-(912)Изобретательство-(14524)Иностранные языки-(4268)Информатика-(17799)Искусство-(1338)История-(13644)Компьютеры-(11121)Косметика-(55)Кулинария-(373)Культура-(8427)Лингвистика-(374)Литература-(1642)Маркетинг-(23702)Математика-(16968)Машиностроение-(1700)Медицина-(12668)Менеджмент-(24684)Механика-(15423)Науковедение-(506)Образование-(11852)Охрана труда-(3308)Педагогика-(5571)Полиграфия-(1312)Политика-(7869)Право-(5454)Приборостроение-(1369)Программирование-(2801)Производство-(97182)Промышленность-(8706)Психология-(18388)Религия-(3217)Связь-(10668)Сельское хозяйство-(299)Социология-(6455)Спорт-(42831)Строительство-(4793)Торговля-(5050)Транспорт-(2929)Туризм-(1568)Физика-(3942)Философия-(17015)Финансы-(26596)Химия-(22929)Экология-(12095)Экономика-(9961)Электроника-(8441)Электротехника-(4623)Энергетика-(12629)Юриспруденция-(1492)Ядерная техника-(1748)

Создаем собственный делегат

Делегаты – начинаем непосредственную работу

Виды методов

Все методы в среде.NET можно разделить на две группы: статические (static) и экземплярные (instance).

Если делегат ссылается на статический метод, то все действительно просто. Так как в этом случае есть вся необходимая для вызова метода информация: адрес метода и параметры. Если же делегат ссылается на экземплярный метод, то задача усложняется. Чтобы вызвать экземплярный метод, делегату необходимо знать ссылку на объект, к которому привязан данный конкретный метод. Оказывается, что эта ссылка хранится в самом объекте делегата и указывается при его создании. На протяжении всей жизни объекта делегата данная ссылка не изменяет своего значения, она всегда постоянна и может быть задана только при его создании. Таким образом, вне зависимости от того, ссылается ли делегат на статическую функцию или на экземплярный метод, обращение к нему извне ничем отличаться не будет. Всю необходимую функциональность обеспечивает сам делегат, вкупе со средой исполнения. Это очень удобно, поскольку множество разных делегатов можно привязывать к одному событию.

Итак, делегат представляет собой экземпляр пользовательского класса, являющегося потомком класса MulticastDelegate. Соответственно, необходимо уметь объявлять подобные классы. Напрямую проделать операцию наследования от класса MultiCastDelegate или Delegate не получится, при попытке сделать это, компилятор выдаст следующую ошибку.

error CS0644: 'Hello' cannot inherit from special class 'System.Delegate'

В переводе на русский язык сообщение означает: "Hello не может быть наследником специального класса System.Delegate". Наследование запрещает сам компилятор и только для этих классов, потому что в большинстве компиляторов предусмотрены специальные средства для работы с делегатами. В C# это специальная конструкция, начинающаяся с ключевого слова delegate.

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

delegate void MyDelegate(string s);

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

class MyDelegate: MulticastDelegate{... // Здесь специальным образом закодирован прототип метода, на который // мы собираемся ссылаться при помощи экземпляров делегата.

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

Создание экземпляра делегата просто, поскольку компилятор уже подготовил все необходимое. Он создал специальный конструктор, которому нужно передать указатель на метод, а со всем остальным разберется среда исполнения.

Создание экземпляра делегата происходит следующим образом:

MyDelegate del = new MyDelegate(MyHandler);

Где MyDelegate — это тип делегата, del — экземпляр делегата, который будет создан в результате выполнения конструкции, MyHandler — метод, на который будет ссылаться этот делегат. Соответственно, после создания экземпляра делегата можно обращаться к методам, на которые он ссылается. В языках высокого уровня существует возможность обращаться к экземпляру делегата, как к самому методу. Выглядеть это будет так.

del("Hello, world!");

Эта строка вызовет метод MyHandler, на который ссылается наш делегат. В завершение приведу пример, который будет аккумулировать сказанное ранее и наглядно демонстрировать работу с простейшим делегатом.

Листинг 2. Простейший пример работы с делегатами.

using System;// Основной класс приложения.class App{ // Опишем собственный делегат. // В этом случае — это не что иное, как описание // вложенного класса, просто оно замаскировано // при помощи специального ключевого слова языка. // Соответственно, для того чтобы использовать данный // класс, придется создать его экземпляр. delegate void MyDelegate(string s); // Это функция, которую мы будем использовать для проверки // работоспособности делегата. // Она является статической и для ее вызова // не требуется наличия экземпляра класса. static void MyHandler(string s) { // Просто выведем на консоль единственный аргумент, // переданный функции. Console.WriteLine(s); } // Точка входа в приложение. static void Main() { // Создадим экземпляр нашего делегата (типа! (класса!)), // описанного нами ранее, передав ему в качестве // параметра конструктора ссылку на функцию, // которую мы хотим связать с делегатом. MyDelegate del = new MyDelegate(MyHandler); // Вызовем функцию через делегат, // как видите, все достаточно просто, мы можем пользоваться // экземпляром делегата как функцией. del("Hello World"); }};

В результате работы приложения на консоль будет выведена следующая строка:

Hello, World!

Возникает естественный вопрос: "А к чему, собственно, такие сложности, не проще ли напрямую обратиться к методу MyHandler?" Оказывается, не проще. Хотя для данного примера, действительно, проще, поскольку мы точно знаем, какой метод нам нужно вызвать. Но для проектирования обратной связи с внешними системами делегаты незаменимы. Мы просто передаем внешней системе делегат, ссылающийся на наш внутренний метод. И покорно ждем, когда внешняя система обратится к нашей внутренней функции через переданный делегат.

<== предыдущая лекция | следующая лекция ==>
Общие сведения. Делегаты являются ссылками на методы, инкапсулирующими настоящие указатели и предоставляющими удобные сервисы для работы с ними | Делегат и экземплярные методы
Поделиться с друзьями:


Дата добавления: 2014-01-07; Просмотров: 277; Нарушение авторских прав?; Мы поможем в написании вашей работы!


Нам важно ваше мнение! Был ли полезен опубликованный материал? Да | Нет



studopedia.su - Студопедия (2013 - 2024) год. Все материалы представленные на сайте исключительно с целью ознакомления читателями и не преследуют коммерческих целей или нарушение авторских прав! Последнее добавление




Генерация страницы за: 0.007 сек.