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

 


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