Поняття делегату. Використання делегатів у програмі

Частина 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);

    CF = Get_Area; // делегат CF посилається на Get_Area
    area = CF(radius);

    CF = Get_Volume; // делегат CF посилається на Get_Volume
    volume = CF(radius);

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

 


Зв’язані теми