На этом шаге мы рассмотрим пример использования делегата, когда он является полем в классе.
Начиная с этого шага мы рассмотрим несколько примеров, которые иллюстрируют красоту и мощь делегатов. Начнем с примера, в котором экземпляр делегата (точнее, переменная, которая может ссылаться на экземпляр делегата) является полем в классе.
using System; using System.Collections.Generic; using System.Linq; using System.Text; namespace pr169_1 { // Объявление делегата: delegate void MyDelegate(string txt); // Класс с полем, являющимся ссылкой на экземпляр делегата: class MyClass { // Поле является ссылкой на экземпляр делегата: public MyDelegate apply; // Конструктор: public MyClass(MyDelegate md) { apply = md; } } // Класс: class Alpha { // Закрытое текстовое поле: private string name; // Метод для присваивания значения полю: public void set(string t) { name = t; } // Переопределение метода ToString(): public override string ToString() { return name; } } // Класс с главным методом: class Program { // Главный метод: static void Main() { // Создание объекта: Alpha A = new Alpha(); // Создание объекта // (аргумент конструктора - ссылка на метод): MyClass obj = new MyClass(A.set); // Вызов экземпляра делегата: obj.apply("Объект A"); // Проверка поля объекта: Console.WriteLine(A); // Создание объекта: Alpha B = new Alpha(); // Полю значением присваивается ссылка на метод: obj.apply = B.set; // Вызов экземпляра делегата: obj.apply("Объект B"); // Проверка поля объекта: Console.WriteLine(B); // Добавление метода в список вызовов экземпляра // делегата: obj.apply += A.set; // Вызов экземпляра делегата: obj.apply("Объект X"); // Проверка полей объектов: Console.WriteLine(A + " и " + B); // Удаление метода из списка вызовов экземпляра // делегата: obj.apply -= B.set; // Вызов экземпляра делегата: obj.apply("Объект A"); // Проверка полей объектов: Console.WriteLine(A + " и " + B); // Задержка: Console.ReadLine(); } } }
Результат выполнения программы представлен ниже:
Рис.1. Результат выполнения программы
Делегат MyDelegate объявляется командой
delegate void MyDelegate(string txt); .
Экземпляры делегата смогут ссылаться на методы, имеющие один текстовый аргумент и не возвращающие результат. В классе MyClass описано поле apply, типом которого указан делегат MyDelegate. Это означает, что поле apply может ссылаться на метод (или список методов). Но самое важное - мы можем "вызывать" это поле (передав ему один текстовый аргумент). Также в классе описан конструктор с одним аргументом. Аргумент конструктора тоже примечательный - это переменная md типа MyDelegate. В теле конструктора командой
apply = md;
Еще один класс Alpha имеет закрытое текстовое поле name. Для присваивания значения полю предусмотрен открытый метод set(), имеющий текстовый аргумент и не возвращающий результат. Для считывания значения поля name мы переопределяем метод ToString() (метод результатом возвращает значение поля name).
В методе Main() командой
Alpha A = new Alpha();
MyClass obj = new MyClass(A.set);
apply = md; ,
Поэтому при выполнении команды
obj.apply("Объект A"); ,
Console.WriteLine(A); .
Затем командой
Alpha B = new Alpha();
obj.apply = B.set;
obj.apply("Объект B");
Console.WriteLine(B); .
Командой
obj.apply += A.set;
obj.apply("Объект X"); ,
Console.WriteLine(A + " и " + B); .
Наконец, выполнение команды
obj.apply -= B.set;
obj.apply("Объект A");
На следующем шаге мы продолжим изучение этого вопроса.