Делегаты. Часть 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 экземпляров объектов класса.

 


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