Училищен курс по програмиране на C# (2013/2014), занятие №14

626 views

Published on

Училищен курс по програмиране на C# (2013/2014)
Занятие №14: Делегати. Събития. Ламбда функции

Published in: Education
0 Comments
0 Likes
Statistics
Notes
  • Be the first to comment

  • Be the first to like this

No Downloads
Views
Total views
626
On SlideShare
0
From Embeds
0
Number of Embeds
1
Actions
Shares
0
Downloads
22
Comments
0
Likes
0
Embeds 0
No embeds

No notes for slide

Училищен курс по програмиране на C# (2013/2014), занятие №14

  1. 1. 2013 Курс по програмиране на C# Занятие №14 Делегати. Събития. Ламбда функции
  2. 2. Съдържание • Функциите като данни • Делегати • Събития и обработчици • Ламбда функции • Примери за употреба на делегати и събития
  3. 3. Функциите като данни • Какво е функция - преговор – Подпрограма, която извършва определена дейност и може да бъде извиквана от друга част на програмата – Нула или повече параметри • Тип на параметъра • Вид на параметъра – предаван по стойност, по референция или изходен – Тип на връщания резултат или липса на такъв – Блок от операции (тяло на функцията)
  4. 4. Функциите като данни • Разглеждане на функции като данни – Някои езици за програмиране боравят с типове данни, чиито дефиниционни множества обхващат семейства от функции – На практика това означава, че: • Функция може да бъде присвоена на променлива или член-данна от подходящия тип • Фунцкия може да бъде подадена като аргумент на друга функция (композиция на функции) • Функция може да бъде върната като резултат от изпълнението на друга функция – Механизъм за метапрограмиране: въвеждане в програмата на кратки и лесни за употреба конструкции, които заместват еднотипни фрагменти от код
  5. 5. Функциите като данни • Функционални типове данни – Дефиниционно множество: функциите с определен брой, тип и вид на параметрите и тип на връщания резултат – Предоставят механизъм за извикване на функцията, която се разглежда като данна
  6. 6. Делегати • Какво е „делегат“? – Референтен тип данни – C# еквивалент на функционален тип данни – Наследява класа System.MulticastDelegate – Наименование – Нула или повече параметри – Тип на връщания резултат – Шаблонни делегати – аналогично на другите шаблонни типове
  7. 7. Делегати // Делегат с един целочислен параметър // и целочислен резултат delegate int UnaryMethod(int x); // Делегат с два целочислени параметъра // и целочислен резултат delegate int BinaryMethod(int x, int y); // Делегат с два низови параметъра // и без резултат public delegate void NameChangedHandler( string oldName, string newName); // Шаблонен делегат с един параметър // от тип, който имплементира интерфейса // IComparable, и същия тип на резултата delegate T UnaryMethod<T>(T x) where T : IComparable; • Деклариране на делегати – Модификатор за достъп (незадължителен) – Ключова дума delegate – Тип на връщания резултат или ключова дума void – Наименование – уникално в рамките на пространството от имена – Списък от параметри в кръгли скоби • Деклариране на шаблонни делегати – Аналогично на декларирането на други шаблонни типове
  8. 8. Деклариране на делегати - демо // Демонстрация
  9. 9. Делегати • Използване на делегати – Делегатите са пълноправни типове данни – Автоматично предоставен конструктор с един параметър – При създаване на делегатен екземпляр, на конструктора се подава като аргумент обръщение към метод без кръгли скоби с аргументи • Методът трябва да има подходящият брой, тип и вид параметри, както и тип на връщания резултат – За изпълнение на метода, съдържащ се в делегатен екземпляр, се поставят кръгли скоби с аргументи след променливата/израза, рефериращ делегатния екземпляр
  10. 10. Делегати static int Add(int x, int y) { return x + y; } static double AddPi(double x) { return x + Math.PI; } static void Main(string[] args) { // Създаване на делегатен екземпляр BinaryMethod binaryMethod = new BinaryMethod(Add); // Съкратен запис за горното BinaryMethod binaryMethod2 = Add; // Създаване на делегатен екземпляр, // чийто тип е шаблонен екземпляр UnaryMethod<double> unaryMethod = AddPi; // Изпълняване на делегатен екземпляр int a = binaryMethod(2, 5); Console.WriteLine(a); } • Използване на делегати – Деклариране на променлива от делегатен тип – Създаване на делегатен екземпляр – Неявно създаване на делегатен екземпляр – извикването на констурктора може да бъде пропуснато – Извикване на метода, към който сочи делегатен екземпляр
  11. 11. Използване на делегати - демо // Демонстрация
  12. 12. Делегати • Приложения на делегатите – Изпълнение на различни операции (определяни по време на изпълнение) върху еднотипни данни – Реализиране на взаимодействия между обекти чрез събития – Функции от по-висок ред – функционално програмиране в C#
  13. 13. Събития • Какво е „събитие“? – Член на клас, структура или интерфейс – Служи за реализиране на взаимодействие между обекти – Тип данни – делегат – Наименование – уникално в рамките на членовете на класа – Към събитието се закачат обработчици – делегатни екземпляри – При предизвикването на събитието се извикват последователно всички закачени обработчици
  14. 14. Събития class Person { // Частно поле за съхранение // на обработчици на събитието private NameChangedHandler _nameChanged; // Събитие с явно декларирани блокове // за закачане и откачане на обработчици public event NameChangedHandler NameChanged { // Блок за закачане на обработчик add { _nameChanged += value; } // Блок за откачане на обработчик remove { _nameChanged -= value; } } // Съкратен запис на горното public event NameChangedHandler NameChanged2; } • Деклариране на събития – Модификатор за достъп (незадължителен) – Ключова дума event – Делегатен тип данни – Наименование – Блокове за закачане и откачане на обработчици (незадължителни) • Блок за закачане – предшества се от стандартната дума add • Блок за откачане – предшества се от стандартната дума remove – Ако блоковете се пропуснат, компилаторът генерира частно поле от същия тип, към което да закача обработчиците (автоматично генерирано събитие)
  15. 15. Деклариране на събития - демо // Демонстрация
  16. 16. Събития // Метод – обработчик на събитието static void PersonNameChanged( string oldName, string newName) { Console.WriteLine( "The person’s name was changed to '{0}'.", newName); } static void Main(string[] args) { Person person = new Person("Иван Петров"); // Закачане на обработчик на събитие person.NameChanged += PersonNameChanged; // Изпълняване на код, който би предизвикал // събитието person.Name = "Георги Георгиев"; // Откачане на обработчик на събитие person.NameChanged -= PersonNameChanged; } • Закачане и откачане на обработчици на събития – Не се допуска директно присвояване на стойност на събитие – Обработчик на събитие се закача с оператора += – Обработчик на събитие се откача с оператора -=
  17. 17. Закачане и откачане на обработчици на събития - демо // Демонстрация
  18. 18. Събития class Person { // ... private string _name; public Person(string name) { _name = name; } public string Name { get { return _name; } set { if (_name == value) return; string oldName = _name; _name = value; if (_nameChanged != null) _nameChanged(oldName, _name); } } } • Предизвикване на събития – Автоматично генерираните събития се предизвикват по същия начин, както се изпълняват делегатни екземпляри – Останалите събития не се предизвикват пряко, а трябва да бъде изпълнен делегатният екземпляр, към който add блокът на събитието закача обработчиците – Ако няма закачени обработчици, събитието има стойност null; при опит за предизвикването му се предизвиква изключение от тип System.NullReferenceException
  19. 19. Предизвикване на събития - демо // Демонстрация
  20. 20. Събития • Приложения на събитията – Реализиране на взаимодействия между обекти – Разширяване и модифициране на поведението на обекти без пряк достъп до реализацията им и без наследяване – Програмиране, базирано на събития – Приложения с графичен потребителски интерфейс
  21. 21. Ламбда функции • Какво е „ламбда функция“? – Специален синтаксис за създаване на делегатен екземпляр – Може да се декларира директно в тялото на друг метод или дори друга ламбда функция – Параметри – типовете им може да бъдат пропуснати – Тяло – Тип на връщания резултат – не се посочва явно – В тялото на ламбда функцията могат да се използват локалните променливи на метода, в който е декларирана
  22. 22. Ламбда функции // Деклариране на ламбда функция с израз BinaryMethod add = (int x, int y) => x + y; // Ламбда функция без явно декларирани типове // на параметрите BinaryMethod subtract = (x, y) => x - y; // Ламбда функция с един параметър UnaryMethod<double> addPi = x => x + Math.PI; // Деклариране на ламбда фунцкия със съждения Person person = new Person("Иван Петров"); person.NameChanged += (oldName, newName) => { Console.WriteLine( "The person’s name changed to '{0}'.", newName); }; • Деклариране на ламбда функции – Списък от параметри в кръгли скоби • Посочването на типовете на параметрите не е задължително • Ако параметърът е един, скобите не са задължителни – Оператор => – Тяло • Израз – резултат от изпълнението на ламбда функцията (ламбда функция с израз) • Блок от операции, който може да връща, а може и да не връща резултат (ламбда функция със съждения)
  23. 23. Деклариране на ламбда функции - демо // Демонстрация
  24. 24. Ламбда функции // Използване на локалнa променливa // в ламбда функция int n = 15; UnaryMethod addN = x => x + n; Console.WriteLine(addN(10)); // Промените в стойността на променливата // след декларацията на функцията се // отразяват на поведението ѝ n = 20; Console.WriteLine(addN(10)); • Използване на локални променливи в ламбда функции – В тялото на ламбда функция може да се използват локалните променливи от метода, в който е декларирана – Стойностите на локалните променливи на метода не се копират при декларирането на ламбда функцията и промените в тях след декларацията ѝ се отразяват на нейното поведение – Това може да доведе до трудно откриваеми грешки
  25. 25. Използване на локални променливи в ламбда функции - демо // Демонстрация
  26. 26. Ламбда функции • Приложения на ламбда функциите – Кратък синтаксис за създаване на делегатни екземпляри – Подходящи, когато делегатният екземпляр ще бъде използван на едниствено място в програмата – Необходими, когато делегатният екземпляр трябва да използва локални променливи на друг метод – Доближават синтаксиса на C# до функционалното програмиране – Правят кода по-четим, премахвайки излишната пунктуация и декларации
  27. 27. Примери за употреба на делегати и събития - демо // Демонстрация
  28. 28. Задачи за упражнение • Създайте конзолно приложение – калкулатор, като използвате подходящи делегати и делегатни екземпляри за реализиране на различните аритметични операции • Преработете конзолния калкулатор в приложение с графичен потребителски интерфейс и поведение, което е сходно на вградения в Windows калкулатор
  29. 29. Задачи за упражнение • Преработете програмата „ролева игра“, като реализирате събития за важни ситуации в играта и походящи обработчици, които да извършват промени в поведението на програмата или да извеждат на екрана подходящи съобщения; примери за такива ситуации са: – Раняване на чудовище – Раняване на играч – Смърт на чудовище – Смърт на играч – Опит за придвижване в неразрешена посока – Попадане в капан и т.н.
  30. 30. Въпроси?
  31. 31. Благодаря! • Александър Далемски – sasho@david.bg – Skype: musasho – https://facebook.com/adalemski • ДАВИД академия – acad@david.bg – http://acad.david.bg/ – @david_academy – https://facebook.com/DavidAcademy

×