Пример использования делегата

Понятие делегата

 

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

В языке 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; просмотров: 437;


Поиск по сайту:

При помощи поиска вы сможете найти нужную вам информацию.

Поделитесь с друзьями:

Если вам перенёс пользу информационный материал, или помог в учебе – поделитесь этим сайтом с друзьями и знакомыми.
helpiks.org - Хелпикс.Орг - 2014-2024 год. Материал сайта представляется для ознакомительного и учебного использования. | Поддержка
Генерация страницы за: 0.015 сек.