C# — делегаты, события и лямбда выражения

(краткая шпаргалка)

В начале была функция обратного вызова. Можно было сконфигурировать одну функцию так, чтобы она осуществляла обратный вызов другой функции в приложении. Таким образом осуществлялась двусторонняя коммуникация между двумя программными сущностями и в приложении.

В .NET Framework обратные вызовы также возможны, и их функциональ­ность обеспечивается в безопасной и объектно-ориентированной манере с использованием делегатов.

По сути, делегат — это безопасный в отношении типов объект, указывающий на другой метод (или, методы) приложения, который может быть вызван позднее.

Объект делегата поддерживает три важных фрагмента информации:

  • адрес метода, на котором он вызывается;
  • аргументы (если есть) этого метода;
  • возвращаемое значение (если есть) этого метода.

Объявление делегата явно

Суть задачи: создать объект, который способен вызвать функцию обратного вызова, которую ему назначают извне.

class Program
    {
        static void Main(string[] args)
        {
            Car car = new Car("Vasia", 0);
            //Добавим функцию для вызова из объекта
            car.AddHandler(Warning);
            for (int i = 0; i < 11; i++)
                car.Accelerate();
            Console.ReadLine();
        }
        //Функция для обратного вызова 
        static public void Warning(object obj, string msg)
        {
            Car car = obj as Car;
            if (car != null)
            {
                Console.WriteLine("Car {0} send message {1}", car.Name, msg);
            }

        }
    }

    class Car
    {
        public string Name { get; set; }
        public int Speed { get; set; }

        private const int MAXSPEED = 100;
        public Car(string name, int speed)
        {
            Name = name;
            Speed = speed;
        }
        //объявление делегата - типа ООП указателя на функцию данной сигнатуры
        public delegate void CarEngineHandler(object sender, string msg);
        //объявление объекта делегата
        private CarEngineHandler cHandler;
        //инициализация объекта делегата указателем на функцию
        public void AddHandler(CarEngineHandler handler)
        {
            cHandler += handler;
        }
        //удаление из объекта делегата данного указателя на функцию
        public void DelHandler(CarEngineHandler handler)
        {
            cHandler -= handler;
        }
        //вызов обратных функций при изменении состояния объекта Car
        public void Accelerate()
        {
            Speed += 10;
            if (Speed > (MAXSPEED / 2) && Speed <= MAXSPEED)
            {
                if (cHandler != null)
                    cHandler(this, "You are about to blow!!!");
            }
            else if (Speed > MAXSPEED)
            {
                if (cHandler != null)
                    cHandler(this, "You blow!!!");
            }
        }
    }

Инициализация делегата при помощи ключевого слова event

Для добавления к делегату функции обратного вызова приходится создавать в объекте Car искусственные функции, например AddHandler(CarEngineHandler handler). Работу этой функции, инициализацию объекта делегата функцией обратного вызова, может выполнить для нас ключевое слово event

class Program
    {

        static void Main(string[] args)
        {
            Car car = new Car("Vasia", 0);
            //добавление функции для обработка события
            car.cHandler += Warning;
            for (int i = 0; i < 11; i++)
                car.Accelerate();
            Console.ReadLine();
        }

        static public void Warning(object obj, string msg)
        {
            Car car = obj as Car;
            if (car != null)
            {
                Console.WriteLine("Car {0} send message {1}", car.Name, msg);
            }

        }
    }

    class Car
    {
        public string Name { get; set; }
        public int Speed { get; set; }

        private const int MAXSPEED = 100;
        public Car(string name, int speed)
        {
            Name = name;
            Speed = speed;
        }
        //объявление типа делегата
        public delegate void CarEngineHandler(object sender, string msg);
        //ключевое слово event
        public event CarEngineHandler cHandler;


        //вызов функции обратного вызова по собтию
        public void Accelerate()
        {
            Speed += 10;
            if (Speed > (MAXSPEED / 2) && Speed <= MAXSPEED)
            {
                if (cHandler != null)
                    cHandler(this, "You are about to blow!!!");
            }
            else if (Speed > MAXSPEED)
            {
                if (cHandler != null)
                    cHandler(this, "You blow!!!");
            }
        }
    }

Обобщенный делегат EventHandler<T>  где Т – тип наследник EventArgs

static void Main(string[] args)
        {
            Car car = new Car("Vasia", 0);
            //добавление обработчик события - обычная функция
            car.cHandler += Warning;
            //добавление обработчик события - анонимная функция
            //use anoym function
            car.cHandler += delegate(object obj, CarEventArgs arg)
            {
                Console.WriteLine("This anonym method - speed {0}", car.Speed);

            };
            //обработчик события в стиле лямбда ввражения
            //use lamda expession
            car.cHandler += ((object obj, CarEventArgs arg) => { Console.WriteLine("This lamda {0}", car.Speed); });
            for (int i = 0; i < 11; i++)
                car.Accelerate();
            Console.ReadLine();
        }

        static public void Warning(object obj, CarEventArgs arg)
        {
            Car car = obj as Car;
            if (car != null)
            {
                Console.WriteLine("Car {0} send message {1}", car.Name, arg.Message);
            }

        }
    }

    class Car
    {
        public string Name { get; set; }
        public int Speed { get; set; }

        private const int MAXSPEED = 100;
        public Car(string name, int speed)
        {
            Name = name;
            Speed = speed;
        }
        // используем обобщенный делегат
        public event EventHandler<CarEventArgs> cHandler;

       

        public void Accelerate()
        {
            Speed += 10;
            if (Speed > (MAXSPEED / 2) && Speed <= MAXSPEED)
            {
                CarEventArgs args = new CarEventArgs("You are about blow!!!");

                cHandler(this, args);
            }
            else if (Speed > MAXSPEED)
            {
                CarEventArgs args = new CarEventArgs("You are blown!!!");

                cHandler(this, args);
            }
        }
    }
    //наследием стандартный объект аргументов события
    class CarEventArgs : EventArgs
    {

        public string Message { get; set; }
        public CarEventArgs(string mes)
            : base()
        {

            Message = mes;
        }
    }

Анонимная функция в качестве функции обратного вызова

//use anoym function
            car.cHandler += delegate(object obj, CarEventArgs arg)
            {
                Console.WriteLine("This anonym method - speed {0}", car.Speed);

            };

Можно, также, использовать лямбда выражение

//use lamda expession
            car.cHandler += ((object obj, CarEventArgs arg) => { Console.WriteLine("This lamda {0}", car.Speed); });
            for (int i = 0; i < 11; i++)
                car.Accelerate();
            Console.ReadLine();

67 комментариев: C# — делегаты, события и лямбда выражения

Добавить комментарий

Ваш адрес email не будет опубликован. Обязательные поля помечены *

Найти на сайте
Со страниц сайта
Последние комментарии
Метки
хохмаУмные мыслиармейский юморДела семейныеДокторинформацияой болитфольклорВовочка & kidsВадим ЗверевПолитическиеСтатусы ВКотактеСобрание скороговорокБольшие и малые народностиПро животныхЗаконы МерфиженщиныПро это...Забойный наборНиколай ФоменкоВсякая всякотаалкоманы-наркоголикиВиктор ШендеровичПро услуги и рестораныБородатые анекдотыавтомобилистыТуристы и турыИскусство и киноКозьма ПрутковПро работуПро студентовОмар ХайямЧерномырдинСтатусы про женщин и мужчинВ общественном транспортеПро сумасшедшихСтанислав Ежи ЛецКриминальныеПро ШтирлицаСтас ЯнковскийСмешные статусыДурацкие законыПро юристовпро самолетыПечалькаПро братковХорошие советыНе та ориентацияМарк ТвенСтатусы про жизньНа селеКрасноармейскиеГусары и поручикиДразнилкиИностранные анекдотыСказочныеХрюн МоржовФрансуа де ЛарошфукоЧерный юморЖан-Жак РуссоОхота и рыбалкаПрограммистыЛеди и джентельменыСпортМультяшкиНа бога надейся...БизнесСчиталкиУильям ШекспирГеоргий ФрумкерФрансис БэконДикий западШутливая лотереяПраздникиБедные и богатыеРаневскаяПьер Огюстен Карон де БомаршеСоветы и ответыДикариИсторические анекдотыНикколо МакиавеллиНаполеон БонапартЗагадкиsongswordpresstraditionalpluginпоговоркиC#старостьЧастушкиmysqlbackendjavascripthostingsshajaxphpстатистикапандемия
Больше Меньше
Архивы
Рейтинг@Mail.ru