8. События и делегаты.pptx
- Количество слайдов: 19
События и делегаты ayuskornyakova@mesi. ru
Зачем нужны делегаты в C# public class My. Math { public double Perform. Operation(string op, double x, double y) { switch (op) { case "+": return x + y; case "-": return x - y; case "*": return x*y; case "/": return x/y; default: throw new Argument. Exception( string. Format("Operation {0} is invalid", op), "op"); } } }
Зачем нужны делегаты в C# public class { private My. Math double Do. Division(double x, double y) { return x / y; } Do. Multiplication(double x, double y) { return x * y; } Do. Subtraction(double x, double y) { return x - y; } Do. Addition(double x, double y) { return x + y; } public double Perform. Operation(string op, double x, double y) { switch (op) { case "+": return this. Do. Addition(x, y); case "-": return this. Do. Subtraction(x, y); case "*": return this. Do. Multiplication(x, y); case "/": return this. Do. Division(x, y); default: throw new Argument. Exception( string. Format("Operation {0} is invalid", op), "op"); } } }
Зачем нужны делегаты в C# private delegate double Operation. Delegate(double x, double y); private Dictionary<string, Operation. Delegate> _operations; public My. Math() { _operations = new Dictionary<string, Operation. Delegate> { { "+", this. Do. Addition }, { "-", this. Do. Subtraction }, { "*", this. Do. Multiplication }, { "/", this. Do. Division }, }; } public double Perform. Operation(string op, double x, double y) { if (!_operations. Contains. Key(op)) throw new Argument. Exception(string. Format("Operation {0} is invalid", op), "op"); return _operations[op](x, y); }
Зачем нужны делегаты в C# private static void Main() { try { var math = new My. Math(); Console. Write. Line(math. Perform. Operation("+", Console. Write. Line(math. Perform. Operation("-", Console. Write. Line(math. Perform. Operation("*", Console. Write. Line(math. Perform. Operation("/", } catch (Exception ex) { Console. Write. Line(ex. Message); } finally { Console. Read. Key(); } } 5, 5, 2));
Понятие типа делегата. NET Делегат — это безопасный в отношении типов объект, указывающий на другой метод (или, возможно, список методов) приложения, который может быть вызван позднее. Объект делегата поддерживает три важных фрагмента информации: адрес метода, на котором он вызывается; аргументы (если есть) этого метода; возвращаемое значение (если есть) этого метода.
Определение типа делегата в C# // Этот делегат может указывать на любой метод, который // принимает два целых и возвращает целое значение, public delegate int Binary. Op(int x, int у);
Базовые классы System. Multicast. Delegate и System. Delegate Multicast. Delegate является специальным классом. Компиляторы и иные средства могут быть производными от этого класса, но его нельзя наследовать явным образом. Multicast. Delegate содержит связный список делегатов, называемый списком вызовов, состоящий из одного или нескольких элементов. При активации группового делегата делегаты в списке вызовов вызываются синхронно в том порядке, в каком они представлены. Если при выполнении этого списка происходит ошибка, выбрасывается исключение. Класс Delegate является базовым для типов делегатов. Однако только система и компиляторы могут явно наследовать классы Delegate и Multicast. Delegate. Также недопустимо создавать новые типы, производные от типа делегата. Класс Delegate не рассматривается как тип делегата, а является классом, наследуемым создаваемыми типами делегатов.
Базовые классы System. Multicast. Delegate и System. Delegate public double Perform. Operation(string op, double x, double y) { if (!_operations. Contains. Key(op)) throw new Argument. Exception(string. Format("Operation {0} is invalid", op), "op"); Console. Write. Line(_operations[op]. Method); Console. Write. Line(_operations[op]. Target); return _operations[op](x, y); }
Обобщенные делегаты delegate возвращаемый_тип имя_делегата<список_параметров_типа>(список_аргументов); public class My. Math { // Создадим обобщенный делегат public delegate T My. Del<T>(T obj 1, T obj 2); public static String Do. Division. String(string x, string y) { return String. Format( @"{0} / {1} = {2} ", x, y, Double. Parse(x) / Double. Parse(y)); } public static double Do. Division(double x, double y) { return x / y; } } private static void Main() { My. Math. My. Del<double> del 1 = My. Math. Do. Division; Console. Write. Line(del 1(5, 2)); My. Math. My. Del<string> del 2 = My. Math. Do. Division. String; Console. Write. Line(del 2("5", "2")); }
//Action объявлен как public delegate void Action(); Action a = () => Console. Write("A"); Action b = () => Console. Write("B"); Action c = a + b; Action d = a - b; a(); Console. Write. Line("__________"); b(); Console. Write. Line("__________"); c();
Понятие события Событием в языке C# называется сущность, предоставляющая две возможности: для класса — сообщать об изменениях, а для его пользователей — реагировать на них. Тип, в котором определены события, как минимум должен поддерживать: регистрацию статического метода типа или экземплярного метода объекта, заинтересованного в получении уведомления о событии; отмену регистрации статического метода типа или экземплярного метода объекта, получающего уведомления о событии; уведомление зарегистрированных методов о том, что событие произошло
Ключевое слово event public class Car { //Максимально доступная скорость машин этого класса private static readonly int max_speed = 10; //Признак того, что а/м сломан public bool Car. Is. Dead = false; //Текущая скорость public int Current. Speed = 0; //Делегат, который будет работать вместе с событиями public delegate void Car. Engine. Handler(string msg); public void Accelerate(int delta) { if (this. Car. Is. Dead) { if (Exploded != null) Exploded("Упс. Машина сдохла. "); } else { this. Current. Speed += delta; if ((this. Current. Speed - 1). Equals(Car. max_speed)) About. To. Blow("Опасность!"); //События, которые может возводить класс Car public event Car. Engine. Handler Exploded; public event Car. Engine. Handler About. To. Blow; if (this. Current. Speed >= Car. max_speed) this. Car. Is. Dead = true; else { Console. Write. Line( "Текущая скорость {0} км/ч", this. Current. Speed); } } }
Прослушивание входящих событий //Имя. Обьекта. Имя. События += new Связанный. Делегат(функция. Для. Вызова) var delegate. Handler = new Car. Engine. Handler(car_Exploded); car. Exploded += delegate. Handler; //Имя. Обьекта. Имя. События -= new Связанный. Делегат(функция. Для. Вызова) car. Exploded -= delegate. Handler;
Прослушивание входящих событий private static void Main() { var car = new Car(); var delegate. Handler = new Car. Engine. Handler(car_Exploded); car. Exploded += delegate. Handler; car. About. To. Blow += car_About. To. Blow; for(var i = 0; i < 13; i++) car. Accelerate(1); car. Exploded -= delegate. Handler; } static void car_About. To. Blow(string msg) { Console. Write. Line(msg); } static void car_Exploded(string msg) { Console. Write. Line(msg); }
Создание специальных аргументов событий public class Event. Args { public static readonly Event. Args Empty; public Event. Args(); } public class Car. Event. Args : Event. Args { public readonly string msg; public Car. Event. Args(string message) { msg = message; } } public class Car { //Делегат public delegate void Car. Engine. Handler(object sender, Car. Event. Args e); /*Остальной код*/ }
Создание специальных аргументов событий public class Car { //Делегат, который будет работать вместе с событиями public delegate void Car. Engine. Handler(object sender, Car. Event. Args e); public void Accelerate(int delta) { if (this. Car. Is. Dead) { if (Exploded != null) Exploded(this, new Car. Event. Args("Упс. Машина сдохла. ")); } else { this. Current. Speed += delta; if ((this. Current. Speed + 1). Equals(Car. max_speed)) About. To. Blow(this, new Car. Event. Args("Опасность!")); if (this. Current. Speed >= Car. max_speed) this. Car. Is. Dead = true; else Console. Write. Line("Текущая скорость {0} км/ч", this. Current. Speed); } } /*Остальной код*/
Создание специальных аргументов событий private static void Main() { var car = new Car(); var param. Delegate. Handler = new Car. Engine. Handler(car_About. To. Blow); car. About. To. Blow += param. Delegate. Handler; for (var i = 0; i < 13; i++) car. Accelerate(1); } static void car_About. To. Blow(object sender, Car. Event. Args e) { if (!(sender is Car)) return; Console. Write. Line(e. msg + " " + (sender as Car). Current. Speed); }
К экзамену • 1) Делегаты. Общие сведения. • 2) Делегаты. Понятие обобщенных делегатов. • 2) События. Общие сведения. Ключевое слово event. Прослушивание событий. • 3) События. Создание специальных аргументов.
8. События и делегаты.pptx