Главная · Карта сайта · Поиск · Статьи · Компьютерные курсы · Обучающие программы · Открытые проекты · Веб-программирование · Создание интернет-сайта · Полезные ссылки · Глоссарий · Контакты · Декабрь 09 2016 22:15:28
Последнее опубликованное

Что такое Model-View-Controller
Pattern Model-View-Controller

Как создать свой веб-сайт
Как создать свой сайт в интернете

Разное
Статистика

Делегаты и события


Применение делегатов
Универсальные делегаты
События
Анонимные делегаты и лямбда - выражения


[Следующая страница]

4.1. Делегаты и полиморфизм

Начнем с делегатов. Делегат в C# - это аналог указателя на функцию в C++. Также, делегаты в C# - это еще один инструмент для реализации полиморфизма. В классической реализации полиморфизма используется механизм виртуальных функций, когда, имея дело с интерфейсом базового класса иерархии, мы можем “общаться” с любыми объектами этой иерархии, как с экземплярами базового класса. За особенности поведения того или иного объекта отвечает частная реализация интерфейса в соответствующем производном классе иерархии. При отсутствии этой частной реализации используется реализация базового класса. Если базовый класс является абстрактным, то в производном классе реализация всех его абстрактных методов просто быть обязана. По сложившейся традиции всю красоту полиморфизма чаще всего демонстрируют на примере иерархии графических объектов Shape, Square, Circle и их общего метода Draw(), отвечающего за “рисование” каждого из них. С этим замечательным и поучительным примером можно познакомиться в MSDN по ссылке http://msdn.microsoft.com/ru-ru/library/ms173152(v=vs.90).aspx.

Вернемся к делегатам. Именно эта гениальная абстракция позволяет нам добиваться похожего эффекта, но уже применительно не к целому классу объектов, а только к отдельному объектов или коллекции объектов. Все просто: методы, помимо обычных параметров-данных, могут принимать на вход указатели на процедуры и функции, которые и определяют поведения вызываемого метода в целом. Другими словами, вызываемому методу, помимо исходных данных передают еще и инструмент, с помощью которого эти данные следует обработать.

В контексте нашей прежней легенды опишем линейные преобразования коллекции геометрических объектов, производных от класса Geometry2D. Класс GeometryTransformation объединяет в себе параметры линейных преобразований, а именно значение поворота, сдвига и масштабирования, и саму логику этих преобразований, реализованную статическими методами Rotate(), Move() и Scale() соответственно. Также, мы определим метод Transform(), который выполняет линейные преобразования коллекции геометрических объектов в соответствии с набором действий группового делегата вида TransformGeometry() (в C# все делегаты являются групповыми - могут содержать ссылки сразу на группу методов). Определение делегата TransformGeometry является частью определения класса GeometryTransformation. Параметры преобразований определяются текущим экземпляром класса GeometryTransformation с помощью его свойств. Пример кода с комментариями представлен ниже:

using System;
using System.Collections.Generic;
namespace CSharpQuickGuide
{
    //Линейные преобразования геометрии
    public class GeometryTransformation
    {
        //Делегат линейных преобразований, определяющий формат (сигнатуру)
        //всех методов, выполняющих любые линейные преобразования с объектом Geometry2D
        public delegate void TransformGeometry(Geometry2D _geometry, GeometryTransformation _transformation);
        //Параметры линейных преобразований (сокращенная форма определения свойств)
        //Поворот
        public double rotation { get; set; }
        //Масштабирование
        public double scale { get; set; }
        //Сдвиг по x и y
        public double dx { get; set; }
        public double dy { get; set; }
        //Реализация (в примере отсутствует) линейных преобразований в соответствии 
        //с делегатом TransformGeometry
        public static void Rotate(Geometry2D _geometry, GeometryTransformation _transformation)
        { throw new NotImplementedException(); }
        public static void Move(Geometry2D _geometry, GeometryTransformation _transformation)
        { throw new NotImplementedException(); }
        public static void Scale(Geometry2D _geometry, GeometryTransformation _transformation)
        { throw new NotImplementedException(); }
        //Выполнение линейных преобразований набора геометрических объектов
        //в соответствии со списком операций _handlers (список методов по сигнатуре TransformGeometry)
        public void Transform(GeometryTransformation.TransformGeometry _handlers
            , GeometrySet<Geometry2D, LinkedList<Geometry2D>> _geometrySet)
        {
            foreach (Geometry2D _geometry in _geometrySet)
                _handlers(_geometry, this);  
        }
    }
    //Пример вызова линейных преобразований для коллекции GeometrySet
    public static class InvokeSample
    {
        public static void Transform(GeometrySet<Geometry2D, LinkedList<Geometry2D>> _geometrySet
            , double _rotation, double _scale, double _dx, double _dy)
        {
            //Создаем делегат TransformGeometry со ссылкой на метод Rotate
            GeometryTransformation.TransformGeometry _handlers = GeometryTransformation.Rotate;
            //Добавляем ссылку на метод Move
            _handlers += GeometryTransformation.Move;
            //Добавляем ссылку на метод Scale
            _handlers += GeometryTransformation.Scale;
            //Создаем и инициализируем объект GeometryTransformation
            //(при создании используем сокращенную форму инициализации свойств объекта)
            GeometryTransformation _transformation = new GeometryTransformation() 
            { rotation = _rotation, scale = _scale, dx = _dx, dy = _dy };
            //Выполняем линейные преобразования
            _transformation.Transform(_handlers, _geometrySet);    
        }
    }
}

Важно: если делегат определяет тип возвращаемого значения, отличного от void, то при присвоении делегату нескольких целевых методов (инициализация группового делегата) и обращении ко всем ним посредством этого делегата, в качестве результата вы получите результат выполнения последнего, присвоенного с использованием оператора +=, метода.



[Следующая страница]

Компьютерные курсы и курсы программирования
Основы программирования

Курс для начинающих программистов на C# и VB.NET.

SQL 25™

Построение SQL запросов и работа с базой данных.

C# Quick Guide™

Программирование на C#. Краткое руководство.

RegEx

Применение регулярных выражений.

Plug-in архитектура

Примеры программной Plug-in архитектуры.

XML и его расширения

Язык разметки XML и его расширения с примерами.

HTML и разметка гипертекста

Языки HTML, XHTML и CSS с примерами разметки.

Основы веб-дизайна

Основы веб-дизайна: решения типовых задач верстки.

Программирование на PHP

Руководство по программированию на PHP для начинающих.

Справочные материалы

Шаблоны проектирования
Каталог шаблонов проектирования программных компонентов.

Рефакторинг кода
Каталог приемов рефакторинга программного кода.

Гость
Имя

Пароль



Забыли пароль?
Запросите новый здесь
.
Coding Craft. Все права защищены © 2011. Проект Инициативного Народного Фронта Образования - ИНФО-проект.