Upload
thina
View
60
Download
1
Embed Size (px)
DESCRIPTION
Курс по програмиране на C#. Занятие №1 4 Делегати. Събития. Ламбда функции. Съдържание. Функциите като данни Делегати Събития и обработчици Л амбда функции Примери за употреба на делегати и събития. Функциите като данни. Какво е функция - преговор - PowerPoint PPT Presentation
Citation preview
2013Copyright © 2013 DAVID Holding Company
Курс по програмиране на C#
Занятие №14Делегати. Събития. Ламбда функции
Copyright © 2013 DAVID Holding Company
Съдържание
• Функциите като данни• Делегати• Събития и обработчици• Ламбда функции• Примери за употреба на делегати и събития
Copyright © 2013 DAVID Holding Company
Функциите като данни
• Какво е функция - преговор– Подпрограма, която извършва определена дейност и може да
бъде извиквана от друга част на програмата– Нула или повече параметри
• Тип на параметъра• Вид на параметъра – предаван по стойност, по референция или изходен
– Тип на връщания резултат или липса на такъв– Блок от операции (тяло на функцията)
Copyright © 2013 DAVID Holding Company
Функциите като данни
• Разглеждане на функции като данни– Някои езици за програмиране боравят с типове данни, чиито
дефиниционни множества обхващат семейства от функции– На практика това означава, че:
• Функция може да бъде присвоена на променлива или член-данна от подходящия тип
• Фунцкия може да бъде подадена като аргумент на друга функция (композиция на функции)
• Функция може да бъде върната като резултат от изпълнението на друга функция
– Механизъм за метапрограмиране: въвеждане в програмата на кратки и лесни за употреба конструкции, които заместват еднотипни фрагменти от код
Copyright © 2013 DAVID Holding Company
Функциите като данни
• Функционални типове данни– Дефиниционно множество: функциите с определен брой, тип и
вид на параметрите и тип на връщания резултат– Предоставят механизъм за извикване на функцията, която се
разглежда като данна
Copyright © 2013 DAVID Holding Company
Делегати
• Какво е „делегат“?– Референтен тип данни– C# еквивалент на функционален тип данни– Наследява класа System.MulticastDelegate– Наименование– Нула или повече параметри– Тип на връщания резултат– Шаблонни делегати – аналогично на другите шаблонни типове
Copyright © 2013 DAVID Holding Company
Делегати
// Делегат с един целочислен параметър// и целочислен резултат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– Наименование – уникално в рамките
на пространството от имена– Списък от параметри в кръгли скоби
• Деклариране на шаблонни делегати– Аналогично на декларирането на
други шаблонни типове
Copyright © 2013 DAVID Holding Company
Деклариране на делегати - демо
// Демонстрация
Copyright © 2013 DAVID Holding Company
Делегати
• Използване на делегати– Делегатите са пълноправни типове данни– Автоматично предоставен конструктор с един параметър– При създаване на делегатен екземпляр, на конструктора се
подава като аргумент обръщение към метод без кръгли скоби с аргументи• Методът трябва да има подходящият брой, тип и вид параметри, както и
тип на връщания резултат
– За изпълнение на метода, съдържащ се в делегатен екземпляр, се поставят кръгли скоби с аргументи след променливата/израза, рефериращ делегатния екземпляр
Copyright © 2013 DAVID Holding Company
Делегати
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);}
• Използване на делегати– Деклариране на променлива от
делегатен тип– Създаване на делегатен екземпляр– Неявно създаване на делегатен
екземпляр – извикването на констурктора може да бъде пропуснато
– Извикване на метода, към който сочи делегатен екземпляр
Copyright © 2013 DAVID Holding Company
Използване на делегати - демо
// Демонстрация
Copyright © 2013 DAVID Holding Company
Делегати
• Приложения на делегатите– Изпълнение на различни операции (определяни по време на
изпълнение) върху еднотипни данни– Реализиране на взаимодействия между обекти чрез събития– Функции от по-висок ред – функционално програмиране в C#
Copyright © 2013 DAVID Holding Company
Събития
• Какво е „събитие“?– Член на клас, структура или интерфейс– Служи за реализиране на взаимодействие между обекти– Тип данни – делегат– Наименование – уникално в рамките на членовете на класа– Към събитието се закачат обработчици – делегатни екземпляри– При предизвикването на събитието се извикват последователно
всички закачени обработчици
Copyright © 2013 DAVID Holding Company
Събития
class Person{ // Частно поле за съхранение // на обработчици на събитието private NameChangedHandler _nameChanged; // Събитие с явно декларирани блокове // за закачане и откачане на обработчици public event NameChangedHandler NameChanged { // Блок за закачане на обработчик add { _nameChanged += value; } // Блок за откачане на обработчик remove { _nameChanged -= value; } } // Съкратен запис на горното public event NameChangedHandler NameChanged2;}
• Деклариране на събития– Модификатор за достъп
(незадължителен)– Ключова дума event– Делегатен тип данни– Наименование– Блокове за закачане и откачане на
обработчици (незадължителни)• Блок за закачане – предшества се от
стандартната дума add• Блок за откачане – предшества се от
стандартната дума remove
– Ако блоковете се пропуснат, компилаторът генерира частно поле от същия тип, към което да закача обработчиците (автоматично генерирано събитие)
Copyright © 2013 DAVID Holding Company
Деклариране на събития - демо
// Демонстрация
Copyright © 2013 DAVID Holding Company
Събития
// Метод – обработчик на събитието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;}
• Закачане и откачане на обработчици на събития– Не се допуска директно присвояване
на стойност на събитие– Обработчик на събитие се закача с
оператора +=– Обработчик на събитие се откача с
оператора -=
Copyright © 2013 DAVID Holding Company
Закачане и откачане на обработчици на събития - демо
// Демонстрация
Copyright © 2013 DAVID Holding Company
Събития
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
Copyright © 2013 DAVID Holding Company
Предизвикване на събития - демо
// Демонстрация
Copyright © 2013 DAVID Holding Company
Събития
• Приложения на събитията– Реализиране на взаимодействия между обекти– Разширяване и модифициране на поведението на обекти без
пряк достъп до реализацията им и без наследяване– Програмиране, базирано на събития– Приложения с графичен потребителски интерфейс
Copyright © 2013 DAVID Holding Company
Ламбда функции
• Какво е „ламбда функция“?– Специален синтаксис за създаване на делегатен екземпляр– Може да се декларира директно в тялото на друг метод или
дори друга ламбда функция– Параметри – типовете им може да бъдат пропуснати– Тяло– Тип на връщания резултат – не се посочва явно– В тялото на ламбда функцията могат да се използват локалните
променливи на метода, в който е декларирана
Copyright © 2013 DAVID Holding Company
Ламбда функции
// Деклариране на ламбда функция с израз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); };
• Деклариране на ламбда функции– Списък от параметри в кръгли скоби
• Посочването на типовете на параметрите не е задължително
• Ако параметърът е един, скобите не са задължителни
– Оператор =>– Тяло
• Израз – резултат от изпълнението на ламбда функцията (ламбда функция с израз)
• Блок от операции, който може да връща, а може и да не връща резултат (ламбда функция със съждения)
Copyright © 2013 DAVID Holding Company
Деклариране на ламбда функции - демо
// Демонстрация
Copyright © 2013 DAVID Holding Company
Ламбда функции
// Използване на локалнa променливa// в ламбда функцияint n = 15;UnaryMethod addN = x => x + n;Console.WriteLine(addN(10));// Промените в стойността на променливата// след декларацията на функцията се// отразяват на поведението ѝn = 20;Console.WriteLine(addN(10));
• Използване на локални променливи в ламбда функции– В тялото на ламбда функция може да
се използват локалните променливи от метода, в който е декларирана
– Стойностите на локалните променливи на метода не се копират при декларирането на ламбда функцията и промените в тях след декларацията ѝ се отразяват на нейното поведение
– Това може да доведе до трудно откриваеми грешки
Copyright © 2013 DAVID Holding Company
Използване на локални променливи в ламбда функции - демо
// Демонстрация
Copyright © 2013 DAVID Holding Company
Ламбда функции
• Приложения на ламбда функциите– Кратък синтаксис за създаване на делегатни екземпляри– Подходящи, когато делегатният екземпляр ще бъде използван
на едниствено място в програмата– Необходими, когато делегатният екземпляр трябва да използва
локални променливи на друг метод– Доближават синтаксиса на C# до функционалното
програмиране– Правят кода по-четим, премахвайки излишната пунктуация и
декларации
Copyright © 2013 DAVID Holding Company
Примери за употреба на делегати и събития - демо
// Демонстрация
Copyright © 2013 DAVID Holding Company
Задачи за упражнение
• Създайте конзолно приложение – калкулатор, като използвате подходящи делегати и делегатни екземпляри за реализиране на различните аритметични операции
• Преработете конзолния калкулатор в приложение с графичен потребителски интерфейс и поведение, което е сходно на вградения в Windows калкулатор
Copyright © 2013 DAVID Holding Company
Задачи за упражнение
• Преработете програмата „ролева игра“, като реализирате събития за важни ситуации в играта и походящи обработчици, които да извършват промени в поведението на програмата или да извеждат на екрана подходящи съобщения; примери за такива ситуации са:– Раняване на чудовище– Раняване на играч– Смърт на чудовище– Смърт на играч– Опит за придвижване в неразрешена посока– Попадане в капан и т.н.
Copyright © 2013 DAVID Holding Company
Въпроси?
Copyright © 2013 DAVID Holding Company
Благодаря!
• Александър Далемски– [email protected]– Skype: musasho– https://facebook.com/adalemski
• ДАВИД академия– [email protected]– http://acad.david.bg/– @david_academy– https://facebook.com/DavidAcademy