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

Часть 1. Понятие делегата. Объявление типа делегата. Использование делегата в программе. Групповое преобразование методов


Содержание


1. Для чего используются делегаты?

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

C# назначение делегат ссылка рисунок

Рис. 1. Назначение делегата

 

2. Какая общая форма объявления типа делегата? Для чего используется ключевое слово delegate?

Чтобы получить делегат, сначала нужно объявить его тип. Тип делегата объявляется с помощью ключевого слова delegate. Ниже приведена общая форма объявления делегата:

delegate возвращаемый_тип имя(список_параметров);

где

  • возвращаемый_тип – обозначает тип значения, которое возвращается методами, которые будут вызваться с помощью делегата;
  • имя – непосредственное имя типа делегата. С помощью этого имени объявляются делегаты таким самым образом как объявляются обычные переменные;
  • список_параметров – параметры, которые необходимы для методов, которые будут вызываться с помощью делегата.

 

3. Какая общая форма объявления делегата?

После объявления типа делегата можно объявлять сам делегат. Общая форма объявления делегата (объекта) точно такая же, как в случае объявления переменной некоторого типа:

тип_делегата имя1 [, имя2, ... ];

где

  • тип_делегата – название типа делегата, который объявляется с помощью ключевого слова delegate (см. п. 2);
  • имя1 , имя2, … – имена делегатов (переменных типа «делегат», объектов, и т.п.). С помощью этих имен можно иметь доступ к методам, на которые ссылаются делегаты.


 

4. Можно ли с помощью делегата вызывать разные методы?

Да. Делегат может вызвать разные методы. Если делегат ссылается на метод1, то чтобы вызвать метод2 с помощью делегата, нужно в этом делегате изменить ссылку на этот метод (метод2).

C# делегат ссылка метод рисунок

Рис. 2. Делегат ссылается на Метод2

 

5. Простейший пример объявления делегата и его использование в программе

Данный пример рассматривается для приложений, которые созданы по шаблону Windows Forms Application.

Пример создания приложения типа Windows Forms Application подробно описывается в теме:

Практическая реализация данного примера подробно описывается в статье:

 

5.1. Условие задачи

В приложении типа Windows Forms Application объявить тип делегата, который ссылается на метод. Требования к сигнатуре метода следующие:

  • метод получает входным параметром переменную типа double;
  • метод возвращает значение типа double, которое есть результатом вычисления.

Реализовать вызов методов с помощью делегата, которые получают радиус R и вычисляют:

  • длину окружности по формуле D = 2 · π · R;
  • площадь круга по формуле S = π · R2;
  • объем шара. Формула: V = 4/3 * π · R3.

Методы должны быть объявлены как статические (с использованием ключевого слова static).

 

5.2. Размышления

Для работы программы выбираем такие имена:

  • название типа делегата – CalcFigure;
  • название делегата (экземпляра объекта) – CF;
  • название метода, который вычисляет длину окружности – Get_Length();
  • название метода, который вычисляет площадь круга – Get_Area();
  • название метода, который вычисляет объем шара – Get_Volume().

Объявление типа делегата и методов осуществляется в классе Form1 главной формы приложения типа Windows Forms Application.

 

5.3. Решение (фрагменты кода)
5.3.1. Объявление типа делегата

Тип делегата объявляется в некотором классе. Это может быть, например, класс основной формы в случае, если приложение создано по шаблону Windows Forms Application.

В классе нужно объявить тип делегата с именем CalcFigure в соответствии с условием задачи. Фрагмент такого объявления приведен ниже:

// объявление типа делегата CalcFigure
delegate double CalcFigure(double r);

 

5.3.2. Объявление методов в классе

Методы в классе объявляются как статические с ключевым словом static.

// объявление статических методов в классе
// длина окружности
public static double Get_Length(double r)
{
    double length;
    length = 2 * 3.1415 * r;
    return length;
}

// площадь круга
public static double Get_Area(double r)
{
    double area;
    area = 3.1415 * r * r;
    return area;
}

// объем шара
public static double Get_Volume(double r)
{
    double volume;
    volume = 3.1415 * r * r * r * 4.0 / 3.0;
    return volume;
}

 

5.3.3. Демонстрация вызова методов с помощью делегата

Демонстрация вызова методов с помощью делегата из другого программного кода, например из обработчика события клика на кнопке (шаблон Windows Forms Application).

// обработчик события button1_Click()
private void button1_Click(object sender, EventArgs e)
{
    double radius, length, area, volume;
    radius = Convert.ToDouble(textBox1.Text);

    // вызов делегата
    // сконструировать делегат
    CalcFigure CF = new CalcFigure(Get_Length);
    length = CF(radius); // 1. Вызов метода Get_Length()

    CF = new CalcFigure(Get_Area);
    area = CF(radius); // 2. Вызов метода Get_Area()

    CF = new CalcFigure(Get_Volume);
    volume = CF(radius); // 3. Вызов метода Get_Volume()

    label2.Text = length.ToString();
    label3.Text = area.ToString();
    label4.Text = volume.ToString();
}

На рисунке 3 схематично изображена работа делегата CF.

C# делегат рисунок ссылка

Рис. 3. Делегат CF

 

6. Как осуществляется групповое преобразование делегированных методов? Пример

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

В вышеприведенном примере (см. п. 5) строку

CF = new CalcFigure(Get_Length);

можно заменить строкой

CF = Get_Length;

что упрощает программный код и наглядность его отображения.

Учитывая вышесказанное, соответствующий обработчик события button1_Click() может иметь следующий вид:

// групповое преобразование делегатов
private void button1_Click(object sender, EventArgs e)
{
    double radius, length, area, volume;
    radius = Convert.ToDouble(textBox1.Text);

    // замена оператора new на оператор присваивания
    // сконструировать делегат с именем CF
    CalcFigure CF = Get_Length; // не нужно оператора new - упрощение кода
    length = CF(radius); // Вызов метода Get_Length()

    CF = Get_Area; // делегат CF ссылается на Get_Area
    area = CF(radius); // Вызов метода Get_Area()

    CF = Get_Volume; // делегат CF ссылается на Get_Volume
    volume = CF(radius); // Вызов метода Get_Volume()

    label2.Text = length.ToString();
    label3.Text = area.ToString();
    label4.Text = volume.ToString();
}

 


Связанные темы