Опубликован: 25.03.2010 | Доступ: свободный | Студентов: 1447 / 158 | Оценка: 4.31 / 4.00 | Длительность: 25:42:00
Лекция 10:

Интерфейсы, делегаты, события в C#

Некоторые члены типа MulticastDelegate

Известно, что в C# методы могут быть статическими ( static ) или экземплярными ( instance ). Статические методы адресуются по имени класса, а экземплярные - по имени экземпляра. При загрузке кода в память компьютера создается единственный объект-тип и несколько объектов-экземпляров. Объект-тип содержит в единственном экземпляре все методы типа и статические данные, общие для всех объектов-экземпляров. А объекты-экземпляры содержат индивидуальные данные, к которым применяются методы объекта-типа. Однако статические методы, которые могут вызываться без создания экземплярных данных, должны обрабатывать только статические данные. Экземплярные же методы могут обрабатывать как индивидуальные, так и общие данные.

Для обычного программирования достаточно рассмотреных нами сведений о делегатах. Но в ряде случаев может потребоваться более тонкая работа с делегатами. Тип MulticastDelegate сам имеет несколько своих собственных членов, но большую часть он наследует от абстрактного класса Delegate. Члены типа MulticastDelegate содержат все необходимые сервисы по управлению делегатами. Некоторые из этих членов экземплярные, а некоторые - статические. Ниже приведены некоторые из сервисов типа MulticastDelegate

Таблица 10.2 . Некоторые члены типа MulticastDelegate, унаследованные от Delegate
Член Пояснения
Method { get; } Возвращает последнюю добавленную в делегат ссылку на метод
Target { get; } Возвращает ссылку на объект, связанный с адресуемым делегатом экземплярным методом
DynamicInvoke() Позволяет динамически обратиться к функциям, привязанным к делегату
GetInvocationList() Возвращает список функций, привязанных к делегату
operator == Перегруженный оператор для сравнения содержимого делегатов
operator != Перегруженный оператор, позволяющий определить различие содержимого делегатов
Combine() Добавляет в объект делегата новую ссылку на функцию
Remove() Удаляет из объекта делегата ссылку на указанную функцию
CreateDelegate() Динамически создает делегат
Свойство Method
using System;
    
namespace Test
{
    class MultiTest
    {
        // Статическое поле
        static int x = 1;
    
        // Объявляем функции с одинаковой сигнатурой
        public void Handler1()
        {
            Console.WriteLine("Исполняется Handler1");
        }
    
        public void Handler2()
        {
            Console.WriteLine("Исполняется Handler2");
        }
    
        public void Handler3()
        {
            Console.WriteLine("Исполняется Handler3");
        }
    }
    
    // Вызывающая сторона
    class MyClass
    {
        public static string Title = "Свойство Method";
    
        // Объявляем делегат как член класса
        delegate void MyDelegate();
    
        public MyClass()
        {
            // Создаем экземпляр класса с методами
            MultiTest obj = new MultiTest();
    
            // Создаем объект-делегат и заполняем ссылками на функции
            // Инициализируем первой ссылкой
            MyDelegate del = new MyDelegate(obj.Handler1);
            // Добавляем другие ссылки
            del += obj.Handler2;
            del += obj.Handler3;
    
            // Вызываем цепочку методов
            del();
            Console.WriteLine();
    
            del.Method.Invoke(obj, null); // Вызываем последний метод
    
            Console.WriteLine("\nПрототип последнего метода:\n{0}",
                del.Method.ToString());
    
            Console.WriteLine("\nИмена адресуемых методов:");
            Delegate[] listMethods = del.GetInvocationList();
            for (int i = 0; i < listMethods.Length; i++)
                Console.WriteLine("{0}", listMethods[i].Method.Name);
        }
    }
    
    // Запуск
    class Program
    {
        static void Main()
        {
            // Настройка консоли
            Console.Title = MyClass.Title;
            Console.ForegroundColor = ConsoleColor.White;
            Console.CursorVisible = false;
            Console.WindowWidth = 30;
            Console.WindowHeight = 14;
    
            new MyClass();// Исполняем
    
            Console.ReadLine();
        }
    }
}
Листинг 10.11 . Применение свойства Method

Свойство Target

Это свойство возвращает объект, связанный с адресуемым делегатом методом.

using System;
    
namespace Test
{
    class MultiTest
    {
        // Объявляем функции с одинаковой сигнатурой
        public void Handler1()
        {
            Console.WriteLine("Исполняется Handler1");
        }
    
        public void Handler2()
        {
            Console.WriteLine("Исполняется Handler2");
        }
    
        public void Handler3()
        {
            Console.WriteLine("Исполняется Handler3");
        }
    }
    
    // Вызывающая сторона
    class MyClass
    {
        public static string Title = "Применение 
    свойства Target делегата";
    
        // Объявляем делегат как член класса
        delegate void MyDelegate();
    
        public MyClass()
        {
            // Создаем экземпляр класса с методами
            MultiTest obj = new MultiTest();
    
            // Создаем объект-делегат и заполняем ссылками на функции
            // Инициализируем первой ссылкой
            MyDelegate del = new MyDelegate(obj.Handler1);
            // Добавляем другие ссылки
            del += obj.Handler2;
            del += obj.Handler3;
    
            // Вызываем цепочку методов
            Console.WriteLine("Многоадресный вызов 
    через делегат");
            del();
            Console.WriteLine();
    
            // Возвращает объект, с которым связан
            // последний адресуемый метод
            Console.WriteLine("Тип объекта: {0}", 
              del.Target.GetType().ToString());
            Console.WriteLine();
    
            // Повышаем полномочия извлеченной из Target ссылки 
            // на объект и повторно адресуемся напрямую 
            Console.WriteLine("Вызов через свойство 
    Target делегата");
            ((MultiTest)del.Target).Handler1();
            ((MultiTest)del.Target).Handler2();
            ((MultiTest)del.Target).Handler3();
            Console.WriteLine();
    
            // Адресуемся напрямую без делегата
            Console.WriteLine("Вызов через объект напрямую");
            obj.Handler1();
            obj.Handler2();
            obj.Handler3();
        }
    }
    
    // Запуск
    class Program
    {
        static void Main()
        {
            // Настройка консоли
            Console.Title = MyClass.Title;
            Console.ForegroundColor = ConsoleColor.White;
            Console.CursorVisible = false;
            Console.WindowWidth = 40;
            Console.WindowHeight = 18;
    
            new MyClass();// Исполняем
    
            Console.ReadLine();
        }
    }
}
Листинг 10.12 . Применение свойства Target

Максим Филатов
Максим Филатов

Прошел курс. Получил код Dreamspark. Ввожу код на сайте, пишет:

Срок действия этого кода проверки уже истек. Проверьте, правильно ли введен код. У вас осталось две попытки. Вы также можете выбрать другой способ проверки или предоставить соответствующие документы, подтверждающие ваш академический статус.

 

Как активировать код?