Пример использования делегата
Понятие делегата
Существует множество задач, в которых необходимо выполнять вычисления с помощью «однотипных» методов, например, с помощью математических функций вещественного типа, имеющих вещественный аргумент (это все тригонометрические функции, логарифмы, экспонента и т.д.). В таких задачах очень хочется получить в свое распоряжение метод, в котором формальным параметром является имя вычисляемой функции или ссылка на имя.
В языке C# методы сами по себе не «гуляют», а могут определяться только внутри некоторых классов.
Поэтому в язык C# был включен специальный класс, позволяющий хранить ссылки на «однотипные» методы. Этот класс получил название Делегат.
Делегат это специальный класс, предназначенный для хранения ссылок на методы.
По определению – переменная типа класс является объектом. Класс, позволяющий описать некоторое множество объектов, каждый из которых является функцией (или ссылкой на функцию), называется функциональным типом.
Таким образом, делегаты в языке C# предназначены для описания функциональных типов. Экземплярами такого класса являются ссылки на функции (методы) – им также как переменным выделяются места в памяти компьютера, начальный адрес которых являются «точками» входа в функции и передаются ссылками.
Эта особенность делегата определила две основные области его применения – самостоятельно для решения некоторых задач (подобно приведенной выше) или для поддержки событий (смотри следующую лекцию).
В этой лекции мы будем рассматривать самостоятельное использование делегатов для решения некоторых задач.
Описание делегата
Формат записи делегата фактически задает сигнатуру (описание) методов, которые могут быть вызваны с его помощью:
[спецификаторы] delegate<тип > <имя> (<параметры>);
где
спецификаторы определяют условия доступа к делегату;
delegate — зарезервированное слово;
<тип> — тип возвращаемого результата;
<имя> — имя делегата (уникальный идентификатор);
<параметры> — формальные параметры вызова.
Например, описание всех функций вещественного типа, имеющих вещественный аргумент, имеет следующий вид:
public delegate double Funk(double argym);
Любая функция, соответствующая этому описанию, может использоваться в качестве параметра вызова умалчиваемого конструктора класса-делегата, который и возвращает конкретный экземпляр делегата – ссылку на функцию. Отличительной особенность работы делегата является формирование ссылок во время работы программы (динамически), а не на этапе ее компиляции.
Пример использования делегата
Для лучшего понимания механизма работы делегата рассмотрим решение следующей задачи: разработать приложение для вычисления пяти функций вещественного типа, имеющих вещественный аргумент: Sin(x), Log(x), Cos(x), Exp(x) и Round(x). Для выбора вычисляемой функции использовать делегат.
Исходный код программы:
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Linq;
using System.Text;
using System.Windows.Forms;
namespace WindowsFormsApplication1
{
public partial class Form1 : Form
{
public Form1()
{
InitializeComponent();
}
public delegate double Funk(double x);//Объявление делегата
public double rab(Funk f, double x) { return f(x); }
//Объявление функции, используюшей делегат
private void button1_Click(object sender, EventArgs e)
{
string st;
double x, y;
textBox2.Text = "";
x = Convert.ToDouble(textBox1.Text);
st="Значение x=" +textBox1.Text+ "\r\n";
textBox2.AppendText(st);
y = rab(Math.Sin, x); // Применение делегата
st = "Sin(x)=" + y.ToString() + "\r\n";
textBox2.AppendText(st);
y = rab(Math.Log, x); // Применение делегата
st = "Log(x)=" + y.ToString() + "\r\n";
textBox2.AppendText(st);
y = rab(Math.Cos, x); // Применение делегата
st = "Cos(x)=" + y.ToString() + "\r\n";
textBox2.AppendText(st);
y = rab(Math.Exp, x); // Применение делегата
st = "Exp(x)=" + y.ToString() + "\r\n";
textBox2.AppendText(st);
y = rab(Math.Round, x); // Применение делегата
st = "Round(x)=" + y.ToString() + "\r\n";
textBox2.AppendText(st);
}
}
}
Работа программы:
Рисунок 13.1 – Использование делегата
Естественно можно навести «красоту» в код программы, например,
private void button1_Click(object sender, EventArgs e)
{
string st;
Funk[] ff={Math.Sin, Math.Log, Math.Cos, Math.Exp,Math.Round};
string[] sfu = { "Sin", "Log", "Cos", "Exp", "Round" };
double x, y;
textBox2.Text = "";
x = Convert.ToDouble(textBox1.Text);
st="Значение x=" +textBox1.Text+ "\r\n";
textBox2.AppendText(st);
for (int i = 0; i < 5; i++)
{
y = rab(ff[i], x);
st = sfu[i]+"=" + y.ToString() + "\r\n";
textBox2.AppendText(st);
}
}
но идея объявления и использования делегата в программе полностью рассмотрена в коде программы этого учебного примера.
Еще раз отметим особенность делегатов – динамически (во время выполнения программы) обращаться к вызываемым методам. Эта особенность делегатов часто используется при создании базовых конструкций программ, в которые можно добавлять различные создаваемые фрагменты, например, фрагменты меню, включающие «однотипные» методы.
Дата добавления: 2018-11-25; просмотров: 427;