240 likes | 398 Views
Курс по програмиране на C#. Занятие № 9 Делегати. Събития. Ламбда функции. Съдържание 1/1. Делегати Събития Ламбда функции. Къде е грешката в кода?.
E N D
Курс по програмиране на C# Занятие №9Делегати. Събития. Ламбда функции
Съдържание 1/1 • Делегати • Събития • Ламбда функции
Къде е грешката в кода? abstractclassVehicle{publicabstractvoid Move();}classCar : Vehicle{publicoverridevoid Move(double distance) {Console.WriteLine("The car moved {0}km.", distance); }}classMotorcycle : Vehicle{publicintEngineVolume { get; set; }}
Къде е проблемът в кода? classBook{publicstring Title { get; set; }publicstring Author { get; set; }}publicclassBooksCollection{privatereadonlyBook[] _books = newBook[100];publicBookthis[int index] {get{ return _books[index] }set{ _books[index] = value; } }publicstringthis[string title] {get {foreach(Bookbookin _books) {if(book != null && book.Title == title)returnbook.ToString(); }returnnull; } }}
Къде е грешката в кода? interfaceINamedObject{stringName { get; }}interfaceIPet : INamedObject{intAge { get; }boolIsVaccinated { get; }}classAnimal{publicintAge;}classDog : IPet, Animal{publicstringName;publicboolIsVaccinated;}
Делегати • Какво е „делегат“? • Тип данни • Множеството от стойности са функциите с конкретен брой и тип параметри и тип на резултата • Служи за съхраняване и предаване на функции като данни • В C# наследява класа System.MulticastDelegate
Делегати • Деклариране на делегати • Ключова дума delegate • Тип на връщания резултат • Наименование – идентификатор в Pascal case • Списък от параметри delegateintBinaryOperation(int x, int y); delegatevoidAction(); delegate T Transformation<T>(T param);
Делегати • Използване на делегати • Могат да бъдат използвани навсякъде, както останалите типове данни • Автоматично генериран конструктор с един параметър • В аргумента на конструктора се поставя обръщение към метод без кръгли скоби с аргументи; методът трябва да бъде със съответстващи на делегата параметри и тип на резултата • Функцията, към която сочи делегатната инстанция, може да бъде изпълнена, като се поставят аргументи в скоби след наименованието на променливата
Делегати delegateintBinaryOperation(int x, int y);classCalculator{publicint Calculate(int x, int y, BinaryOperation operation) {returnoperation(x, y); }}classProgram{staticvoid Main(string[] args) {Calculatorcalculator = newCalculator();intresult = calculator.Calculate(3, 5, newBinaryOperation(Sum));Console.WriteLine(result);Console.ReadLine(); }publicstaticint Sum(int x, int y) {returnx + y; }}
Делегати • Използване на делегати • Може конструирането на делегатна инстанция да се замести директно с обръщение към метод без кръгли скоби с аргументи classProgram{staticvoid Main(string[] args) {Calculatorcalculator = newCalculator();intresult = calculator.Calculate(3, 5, Sum);Console.WriteLine(result);Console.ReadLine(); }publicstaticint Sum(int x, int y) {returnx + y; }}
Делегати • Приложение на делегатите • Изпълнение на различни операции (определяни по време на изпълнение) върху еднотипни данни • Реализиране на взаимодействие между обекти чрез събития • Функции от по-висок ред – доближават C# до функционалното програмиране
Събития • Какво е „събитие“? • Член на клас, структура или интерфейс • Служи за реализиране на взаимодействия между обекти • Тип на делегат и наименование • Уникалност на наименованията • Много делегатни инстанции могат да бъдат закачени към едно събитие • При предизвикването на събитието се изпълняват последователно функциите във всички закачени делегатни инстанции
Събития • Деклариране на събития • Ключова дума event • Тип на делегата • Наименование • Опционално: тяло с add и remove блокове, които вътрешно закачат/откачат подадения параметър към/от поле със същия тип • Ако тялото е пропуснато, компилаторът създава вътрешно поле, в което да съхранява списъка от закачени делегатни инстанции (автоматично генерирано събитие)
Събития delegatevoidNotificationHandler(object data);classNotifier{publicvoid Notify(object data) {if (Notification != null)Notification(data); }publiceventNotificationHandler Notification;}
Събития • Използване на събития • Не се допуска директно присвояване на стойност на събитието • Закачане (абониране) за събитие – с оператора += • Откачане от събитие – с оператора -= • Преди да предизвикаме събитието, проверяваме дали е различно от null • Ако събитието е декларирано с тяло, не изпълняваме събитието, а полето, което съхранява списъка с делегатни инстанции
Събития delegatevoidNotificationHandler(object data);classNotifier{publicvoid Notify(object data) {if(Notification != null)Notification(data); }publiceventNotificationHandler Notification;}classProgram{staticvoid Main(string[] args) {Notifiernotifier = newNotifier();notifier.Notification+= newNotificationHandler(Notifier_Notification);notifier.Notify(42);Console.ReadLine(); }publicstaticvoidNotifier_Notification(object data) {Console.WriteLine("Received notification with data: {0}", data); }}
Събития • Приложение на събитията • Взаимодействия между обекти • Програмиране, базирано на събития • Приложения с графичен потребителски интерфейс
Ламбда функции • Какво е „ламбда функция“? • Специален синтаксис за създаване на делегатна инстанция • Може да се декларира директно в тялото на друг метод или дори на друга ламбда функция • Параметри и тяло; тип на връщания резултат • Може да използва локалните променливи на метода, в който е декларирана
Ламбда функции • Деклариране на ламбда функции • Параметър или списък от параметри (без декларирани типове) • Оператор => • Израз или блок • Типа на резултата се определя от типа на израза, или от типа на аргумента на return в тялото
Ламбда функции delegateintBinaryOperation(int x, int y);classCalculator{publicint Calculate(int x, int y, BinaryOperation operation) {returnoperation(x, y); }}classProgram{staticvoid Main(string[] args) {Calculatorcalculator = newCalculator();intresult = calculator.Calculate(3, 5, (x, y) => x + y);Console.WriteLine(result);Console.ReadLine(); }}
Ламбда функции delegatevoidNotificationHandler(object data);classNotifier{publicvoid Notify(object data) {if(Notification != null)Notification(data); }publiceventNotificationHandler Notification;}classProgram{staticvoid Main(string[] args) {Notifiernotifier = newNotifier();notifier.Notification +=data => {Console.WriteLine("Received notification with data: {0}", data); };notifier.Notify(42);Console.ReadLine(); }}
Ламбда функции • Приложение на ламбда функциите • Кратък запис на делегатна инстанция • Подходящо, ако делегатната инстанция ще се ползва само на едно място в кода • Нужно, когато делегатната инстанция трябва да достъпва локални променливи на метода, в който е декларирана • Сходство с функционалното програмиране • По-четим код
Благодаря! • Александър Далемски • sasho@david.bg • musashi.bg@gmail.com • Skype: musasho • https://www.facebook.com/adalemski • ДАВИД академия • acad@david.bg • http://acad.david.bg/ • @david_academy • https://www.facebook.com/groups/david.academy/