Делегати. Частина 5. Приклади передачі масивів, структур, класів анонімному методу

Делегати. Частина 5. Приклади передачі масивів, структур, класів анонімному методу


Зміст



1. Приклад виклику анонімного методу, що отримує вхідним параметром масив цілих чисел

Оголошення типу делегату з іменем ProcessArray, що отримує вхідним параметром масив чисел і не повертає значення

// оголошення типу делегату, який отримує параметром масив чисел
delegate void ProcessArray(ref int[] A);

Демонстрація роботи делегатів типу ProcessArray з двома анонімними методами. Перший метод занулює всі елементи масиву. Другий метод збільшує значення елементів масиву на 10.
Вихідний код, що демонструє роботу анонімних методів:

// Передача аргументів анонімному методу
// Оголошується делегат типу ProcessArray
// Делегат PA1 занулює масив
ProcessArray PA1 = delegate (ref int[] A)
{
    // занулення масиву цілих чисел
    int i;
    for (i = 0; i < A.Length; i++)
        A[i] = 0;
};

// Делегат PA2 збільшує значення елементів масиву на 10
ProcessArray PA2 = delegate(ref int[] A)
{
    int i;
    for (i = 0; i < A.Length; i++)
        A[i] = A[i] + 10;
};

// Демонстрація роботи делегатів
// Оголошення масиву з 5 цілих чисел
int[] B = new int[5];

// виклик делегату PA1 - занулення масиву
PA1(ref B); // B = [0, 0, 0, 0, 0]

// виклик делегату PA2 - збільшення елементів масиву на 10
PA2(ref B); // B = [10, 10, 10, 10, 10]

  

2. Приклад виклику анонімного методу, що отримує вхідним параметром структуру

Нехай в описі класу задано структуру типу Student:

// Оголошення структури типу Student
struct Student
{
    public string Name;
    public string Address;
    public int Age;
};

Для демонстрації використання анонімного методу в тілі структури потрібно спочатку оголосити тип делегату. Тип делегату оголошується в тому самому класі, що й тип структури. Оголошення делегату, наприклад, може бути таким:

// Оголошення типу делегату
delegate void ShowInfo(Student st);

Нижче наведено програмний код, що демонструє використання типу делегату ShowInfo:

// Демонстрація використання анонімного методу,
// що отримує структуру в якості параметру
// 1. Оголошення анонімного методу
ShowInfo SI;
SI = delegate(Student st)
{
    label1.Text = st.Name;
    label2.Text = st.Address;
    label3.Text = st.Age.ToString();
};

// 2. Оголошення та зповнення структурної змінної Stud
Student Stud;
Stud.Name = "Ivanov I.I.";
Stud.Address = "The address of Ivanov I.I.";
Stud.Age = 118;

// 3. Виклик анонімного методу з допомогою делегату
SI(Stud);

  

3. Приклад анонімного методу, що отримує вхідним параметром масив структур

У прикладі наводиться передача масиву структур типу Student анонімному методу.
Структура типу Student описується в деякому класі і має вигляд:

// Оголошення структури типу Student
struct Student
{
    public string Name;
    public string Address;
    public int Age;

    public void Set(string name, string address, int age)
    {
        Name = name;
        Address = address;
        Age = age;
    }
};

Оголошення типу делегату описується в тому самому класі що і структура Student.

// Оголошення типу делегату
delegate void ShowInfoIndex(Student[] st, int index);

Демонстрація передачі масиву структур анонімному методу

// Передача масиву структур методу
// 1. Оголошення змінної st типу "масив структур"
Student[] st = new Student[3];

// 2. Заповнення масиву структур st значеннями
st[0].Set("Ivanov I.I.", "Minsk", 32);
st[1].Set("Johnson J.J.", "Kiev", 45);
st[2].Set("Kameroon J.", "Las-Vegas", 23);

// 3. Оголошення змінної-делегату з іменем SI
// та програмного коду анонімного методу
ShowInfoIndex SI;
SI = delegate(Student[] ST, int index)
{
    label1.Text = ST[index].Name;
    label2.Text = ST[index].Address;
    label3.Text = ST[index].Age.ToString();
};

// 4. Виклик анонімного методу з допомогою делегату
SI(st, 0); // Буде виведено: {"Ivanov I.I.", "Minsk", 32}
SI(st, 1); // Буде виведено: {"Johnson J.J.", "Kiev", 45}

  

4. Приклад анонімного методу, що отримує вхідним параметром об’єкт екземпляру класу

Нехай задано опис класу, який розміщується в окремому модулі (наприклад “MyClass1.cs”. Код класу наступний

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace TrainDelegates07
{
    // Оголошення класу в модулі "MyClass1.cs"
    class MyClass1
    {
        private int x;
        private double R;

        public int GetX()
        {
            return x;
        }

        public double GetR()
        {
            return R;
        }

        public void SetX(int nx)
        {
            x = nx;
        }

        public void SetR(double nR)
        {
            R = nR;
        }
    }
}

У класі реалізовано дві внутрішні змінні (x, R) та чотири методи що читають та змінюють ці внутрішні змінні.
В іншому класі (модулі) тип делегату оголошується так:

// оголошення типу делегату, що отримує клас MyClass1
delegate void ProcessMyClass(MyClass1 mc);

У методі, що демонструє роботу анонімних методів (наприклад, обробник події) потрібно виконати приблизно такий програмний код

// Демонстрація використання класу
// 1. Оголосити об'єкт класу
MyClass1 MC1 = new MyClass1(); // виділити пам'ять для MC1

// 2. Заповнити поля класу значеннями
MC1.SetX(5);
MC1.SetR(10.5);

// 3. Оголосити делегат типу ProcessMyClass
ProcessMyClass PC;
// делегат посилається на анонімний метод, що отримує клас
PC = delegate (MyClass1 mc)
{
    int x;
    double R;

    // вивід на форму значень x, R
    x = mc.GetX();
    R = mc.GetR();

    label1.Text = x.ToString();
    label2.Text = R.ToString();
};

// 4. Виклик анонімного методу з допомогою делегату
PC(MC1);

  

5. Приклад анонімного методу, що отримує вхідним параметром масив об’єктів екземплярів класів

Умова задачі

Дано клас, що описується в окремому модулі “MyClass1.cs”. Лістинг модуля наступний:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace TrainDelegates08
{
    // оголошення класу MyClass1
    class MyClass1
    {
        private int x;
        private double R;

        public int GetX()
        {
            return x;
        }

        public double GetR()
        {
            return R;
        }

        public void SetX(int nx)
        {
            x = nx;
        }

        public void SetR(double nR)
        {
            R = nR;
        }
    }
}

Потрібно оголосити анонімний метод, що отримує вхідним параметром масив класів типу MyClass1. Демонстрацію використання анонімного методу реалізувати у класі Form1 головної форми додатку за шаблоном Windows Forms Application.

Розв‘язок

Лістинг модуля Form1.cs наступний:

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 TrainDelegates08
{
    public partial class Form1 : Form
    {
        // оголошення типу делегату, що отримує масив класів типу MyClass1
        delegate void ProcessMyClass(MyClass1[] mc, int index);

        public Form1()
        {
            InitializeComponent();
        }

        private void button1_Click(object sender, EventArgs e)
        {
            // Демонстрація передачі масиву класів в анонімний метод
            // 1. Оголосити об'єкт з іменем MC типу "масив з 10 класів"
            MyClass1[] MC;

            // 2. Виділення пам'яті
            // 2.1. Виділити пам'ять для масиву класів в цілому
            MC = new MyClass1[10];

            // 2.2. Виділити пам'ять для кожного елементу масиву (для класу)
            for (int i = 0; i < 10; i++)
                MC[i] = new MyClass1();

            // 3. Заповнити поля масиву класів значеннями
            for (int i=0; i<10; i++)
            {
                MC[i].SetX(i + 1);
                MC[i].SetR(10 * i + 1);
            }

            // 4. Оголосити делегат типу ProcessMyClass
            ProcessMyClass PC;

            // 5. Описати програмний код анонімного методу, що отримує параметром масив класів
            PC = delegate (MyClass1[] mc, int index)
            {
                // вивід на форму значень екзепмляру класу з індексом index
                int x;
                double R;
                x = mc[index].GetX();
                R = mc[index].GetR();
                label1.Text = x.ToString();
                label2.Text = R.ToString();
            };

            // 6. Виклик анонімного методу з допомогою делегату PC
            PC(MC, 5);
        }
    }
}

Пояснимо деякі фрагменти коду.

У класі Form1 оголошується тип делегату, який отримує масив класів в якості вхідного параметру. Фрагмент оголошення має такий вигляд:

// оголошення типу делегату, що отримує масив класів типу MyClass1
delegate void ProcessMyClass(MyClass1[] mc, int index);

В обробнику події button1_Click() продемонстровано використання анонімного методу, що отримує масив класів в якості параметру. Також продемонстровано виділення пам‘яті для масиву з 10 екземплярів об‘єктів класу.

  


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