Помощь в написании студенческих работ
Антистрессовый сервис

Делегаты и обратные вызовы

РефератПомощь в написанииУзнать стоимостьмоей работы

При разработке средств обратного вызова в языке C# было решено обеспечить программистов не только возможностью контролировать сигнатуру методов, но и отличать методы классов от методов объектов. Каждый делегат включает в качестве полей ссылку на объект, для которого нужно вызвать метод, и имя конкретного метода. Если ссылка на объект равна null, то имя метода воспринимается как имя статического… Читать ещё >

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

В программировании достаточно часто возникает необходимость создавать фрагменты кода (например, классы, подпрограммы, функции), которые можно было бы каким-либо образом настраивать при конкретных применениях. Наиболее интересна и важна настройка, позволяющая изменять алгоритм выполнения кода. Классическим примером удобства и полезности такой настройки служат методы Sort () и BinarySearchO класса Array. Первый из них выполняет сортировку элементов массива, второй позволяет осуществлять бинарный поиск нужного значения в упорядоченном массиве. Применение каждого из названных методов требует, чтобы программист-пользователь «сообщил» при вызове, что он понимает под порядком, в котором должны разместиться сортируемые элементы, или что означает равенство значений элемента массива и эталона поиска. Указанные критерии сортировки и поиска оформляются в виде вспомогательных методов. Сведения об этих методах передаются методам Sort () и BinarySearchO в качестве аргументов вместе с тем массивом, который нужно обработать. Благодаря этому в программе пользователя появляется возможность, по-разному программируя вспомогательные методы, достаточно произвольно задавать правила сортировки и поиска, т. е. изменять поведение библиотечных методов Sort () и BinarySearchO.

О концепции построения методов, вызывающих при исполнении вспомогательные функции, определенные (позже) в точке вызова (например, в коде пользователя), говорят, используя термин «обратный вызов» (callback). В примере с Sort () и BinarySearchO методы обратного вызова параметризуют названные библиотечные методы.

Еще один пример применения методов обратного вызова — процедура вывода на экран дисплея графика функции Дх), математическое описание которой заранее не известно. При обращении к такой процедуре могут быть заданы (например) пределы изменения аргумента xmin, xmax и ссылка на программную реализацию конкретной функции Дх).

Третий пример — процедура вычисления определенного интеграла функции Дх). Так как существует много методов численного интегрирования, то при использовании процедуры можно с помощью параметров задать: программную реализацию метода интегрирования, реализацию (метод) подинтегральной функцииДх), пределы интегрирования и требуемую точность вычислений. В данном случае процедура вычисления определенного интеграла параметризуется двумя методами обратного вызова.

Итак, обратным вызовом называют обращение из исполняемого метода к другому методу, который зачастую определяется не на этапе компиляции, а в процессе выполнения программы. В языках С и C + + для реализации обратных вызовов в качестве параметра в процедуру передается указатель на ту функцию, к которой нужно обращаться при исполнении программы. Мы не рассматриваем механизм указателей, но заметим, что указатель на функцию — это адрес участка основной памяти, в котором размещен код функции. Опасность и ненадежность обращения к функции по ее адресу состоит в том, что зная только адрес, невозможно проверить правильность обращения. Ведь нужно убедиться, что количество аргументов и их типы соответствуют параметрам функции, что верен тип возвращаемого значения и т. д.

Возможность указанных проверок в языке C# обеспечивают делегаты.

При разработке средств обратного вызова в языке C# было решено обеспечить программистов не только возможностью контролировать сигнатуру методов, но и отличать методы классов от методов объектов. Каждый делегат включает в качестве полей ссылку на объект, для которого нужно вызвать метод, и имя конкретного метода. Если ссылка на объект равна null, то имя метода воспринимается как имя статического метода.

Как мы уже говорили, делегат — это тип, экземпляры которого представляют методы с конкретной спецификацией параметров и фиксированным типом возвращаемого значения. Делегаты дают возможность рассматривать методы как сущности, ссылки на которые можно присваивать переменным (соответствующего типа) и передавать в качестве параметров.

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

Определим класс, поля которого задают предельные значения xmin, xmax отрезка числовой оси и количество п равноотстоящих точек на этом отрезке. В классе определим метод, выводящий на экран значения функции /(х) в точках числовой оси, определенных значениями Хщщ, *тах' п• Конкретная функция/(х), передается методу с помощью параметра-делегата. Определения делегата-типа и класса:

public delegate double Pnoc (double x); // делегат-тип

public class Series.

{

int n;

double xmi, xma;

public Series (int ni, double xn, double xk) 11 конструктор { n = ni; xmi = xn; xma = xk; } public void display (Proc fun).

{

Console.WriteLine («Proc: {0}, xmi={l:f2}, «+.

" xma={2:f2}, n={3}.", fun. Method, xmi, xma, n); for (double x = xmi; x <= xma; x += (xma — xmi) / (n — 1)) Console. Write («{0:f2} «, fun (x));

} }

Делегат-тип Proc определен как внешний тип в глобальном пространстве имен. Там же определен класс Series. Для нас интересен его метод с заголовком.

public void display (Proc fun).

Параметр метода — ссылка на экземпляр делегата Proc. В теле метода displayO выводится заголовок того метода, который будет представлен аргументом-делегатом. Затем выводятся п значений адресованного аргументом метода, представляющего функцию Дх). Значения выводятся в цикле, параметром которого служит аргумент функции Дх).

Имея такие определения типа-делегата и класса, можно вводить разные методы, соответствующие делегату Proc, и определять разные объекты класса Series. Затем для объекта класса Series можно вызвать метод displayO, передать ему в качестве аргумента имя метода, представляющего нужную математическую функцию Дх), и получить заголовок метода, представляющего функцию Дх), и набор значений этой функции. Указанные действия выполняет следующий фрагмент программы:

class Program.

{

static double mySin (double x) // Математическая функция { return Math. Sin (x); }.

static double myLine (double x) // Математическая функция { return x * 5; } static void Main ().

{

Series sequence = new Series (7, 0.0, 1.0); // Объект класса sequence. display (mySin);

Console.WriteLine (); sequence. display (myLine);

Console.WriteLine ();

}

>

В классе Program определены два статических метода, соответствующих делегату-типу Proc. В методе Main () определен именуемый ссылкой sequence объект класса Series. Поля этого объекта (xmin, xmax, n) определяют набор точек оси аргумента, в которых будут вычисляться значения функции при обращении к методу displayO.

Результат выполнения программы:

Ргос: Double mySin (Double), xmi=0,00, xma=l, 00, n=7.

0,00 0,17 0,33 0,48 0,62 0,74 0,84.

Ргос: Double myLine (Double), xmi=0,00, xma=l, 00, n=7.

0,00 0,83 1,67 2,50 3,33 4,17 5,00.

Обратите внимание, что в данном примере нет явного создания экземпляра делегата Ргос. Нет явного определения и ссылок на экземпляры делегатов. Вместо этого при обращении к методу displayO параметр fun заменяется именем конкретного метода. Все дальнейшие действия выполняются неявно — создается экземпляр делегата-типа Ргос и ссылка на него используется в теле метода.

Показать весь текст
Заполнить форму текущей работой