Занятие №9 на курса по програмиране на C# 2013 провеждан от ДАВИД академия в ПМГ "Никола Обрешков" - Казанлък. Включва темите:
- Делегати
- Събития
- Ламбда функции
3. Къде е грешката в кода?
abstract class Vehicle
{
public abstract void Move();
}
class Car : Vehicle
{
public override void Move(double distance)
{
Console.WriteLine("The car moved {0}km.", distance);
}
}
class Motorcycle : Vehicle
{
public int EngineVolume { get; set; }
}
4. Къде е проблемът в кода?
class Book
{
public string Title { get; set; }
public string Author { get; set; }
}
public class BooksCollection
{
private readonly Book[] _books = new Book[100];
public Book this[int index]
{
get { return _books[index] }
set { _books[index] = value; }
}
public string this[string title]
{
get
{
foreach (Book book in _books)
{
if (book != null && book.Title == title)
return book.ToString();
}
return null;
}
}
}
5. Къде е грешката в кода?
interface INamedObject
{
string Name { get; }
}
interface IPet : INamedObject
{
int Age { get; }
bool IsVaccinated { get; }
}
class Animal
{
public int Age;
}
class Dog : IPet, Animal
{
public string Name;
public bool IsVaccinated;
}
6. Делегати
• Какво е „делегат“?
– Тип данни
– Множеството от стойности са функциите с конкретен
брой и тип параметри и тип на резултата
– Служи за съхраняване и предаване на функции като
данни
– В C# наследява класа System.MulticastDelegate
7. Делегати
• Деклариране на делегати
–
–
–
–
Ключова дума delegate
Тип на връщания резултат
Наименование – идентификатор в Pascal case
Списък от параметри
delegate int BinaryOperation(int x, int y);
delegate void Action();
delegate T Transformation<T>(T param);
8. Делегати
• Използване на делегати
– Могат да бъдат използвани навсякъде, както
останалите типове данни
– Автоматично генериран конструктор с един
параметър
– В аргумента на конструктора се поставя обръщение
към метод без кръгли скоби с аргументи; методът
трябва да бъде със съответстващи на делегата
параметри и тип на резултата
– Функцията, към която сочи делегатната инстанция,
може да бъде изпълнена, като се поставят аргументи в
скоби след наименованието на променливата
9. Делегати
delegate int BinaryOperation(int x, int y);
class Calculator
{
public int Calculate(int x, int y, BinaryOperation operation)
{
return operation(x, y);
}
}
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
int result = calculator.Calculate(3, 5, new BinaryOperation(Sum));
Console.WriteLine(result);
Console.ReadLine();
}
public static int Sum(int x, int y)
{
return x + y;
}
}
10. Делегати
• Използване на делегати
– Може конструирането на делегатна инстанция да се
замести директно с обръщение към метод без кръгли
скоби с аргументи
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
int result = calculator.Calculate(3, 5, Sum);
Console.WriteLine(result);
Console.ReadLine();
}
public static int Sum(int x, int y)
{
return x + y;
}
}
11. Делегати
• Приложение на делегатите
– Изпълнение на различни операции (определяни по
време на изпълнение) върху еднотипни данни
– Реализиране на взаимодействие между обекти чрез
събития
– Функции от по-висок ред – доближават C# до
функционалното програмиране
12. Събития
• Какво е „събитие“?
– Член на клас, структура или интерфейс
– Служи за реализиране на взаимодействия между
обекти
– Тип на делегат и наименование
– Уникалност на наименованията
– Много делегатни инстанции могат да бъдат закачени
към едно събитие
– При предизвикването на събитието се изпълняват
последователно функциите във всички закачени
делегатни инстанции
13. Събития
• Деклариране на събития
Ключова дума event
Тип на делегата
Наименование
Опционално: тяло с add и remove блокове, които
вътрешно закачат/откачат подадения параметър
към/от поле със същия тип
– Ако тялото е пропуснато, компилаторът създава
вътрешно поле, в което да съхранява списъка от
закачени делегатни инстанции (автоматично
генерирано събитие)
–
–
–
–
14. Събития
delegate void NotificationHandler(object data);
class Notifier
{
public void Notify(object data)
{
if (Notification != null)
Notification(data);
}
public event NotificationHandler Notification;
}
15. Събития
• Използване на събития
– Не се допуска директно присвояване на стойност на
събитието
– Закачане (абониране) за събитие – с оператора +=
– Откачане от събитие – с оператора -=
– Преди да предизвикаме събитието, проверяваме дали
е различно от null
– Ако събитието е декларирано с тяло, не изпълняваме
събитието, а полето, което съхранява списъка с
делегатни инстанции
16. Събития
delegate void NotificationHandler(object data);
class Notifier
{
public void Notify(object data)
{
if (Notification != null)
Notification(data);
}
public event NotificationHandler Notification;
}
class Program
{
static void Main(string[] args)
{
Notifier notifier = new Notifier();
notifier.Notification += new NotificationHandler(Notifier_Notification);
notifier.Notify(42);
Console.ReadLine();
}
public static void Notifier_Notification(object data)
{
Console.WriteLine("Received notification with data: {0}", data);
}
}
17. Събития
• Приложение на събитията
– Взаимодействия между обекти
– Програмиране, базирано на събития
– Приложения с графичен потребителски интерфейс
18. Ламбда функции
• Какво е „ламбда функция“?
– Специален синтаксис за създаване на делегатна
инстанция
– Може да се декларира директно в тялото на друг
метод или дори на друга ламбда функция
– Параметри и тяло; тип на връщания резултат
– Може да използва локалните променливи на метода,
в който е декларирана
19. Ламбда функции
• Деклариране на ламбда функции
– Параметър или списък от параметри (без
декларирани типове)
– Оператор =>
– Израз или блок
– Типа на резултата се определя от типа на израза, или
от типа на аргумента на return в тялото
20. Ламбда функции
delegate int BinaryOperation(int x, int y);
class Calculator
{
public int Calculate(int x, int y, BinaryOperation operation)
{
return operation(x, y);
}
}
class Program
{
static void Main(string[] args)
{
Calculator calculator = new Calculator();
int result = calculator.Calculate(3, 5, (x, y) => x + y);
Console.WriteLine(result);
Console.ReadLine();
}
}
21. Ламбда функции
delegate void NotificationHandler(object data);
class Notifier
{
public void Notify(object data)
{
if (Notification != null)
Notification(data);
}
public event NotificationHandler Notification;
}
class Program
{
static void Main(string[] args)
{
Notifier notifier = new Notifier();
notifier.Notification +=
data =>
{
Console.WriteLine("Received notification with data: {0}", data);
};
notifier.Notify(42);
Console.ReadLine();
}
}
22. Ламбда функции
• Приложение на ламбда функциите
– Кратък запис на делегатна инстанция
– Подходящо, ако делегатната инстанция ще се ползва
само на едно място в кода
– Нужно, когато делегатната инстанция трябва да
достъпва локални променливи на метода, в който е
декларирана
– Сходство с функционалното програмиране
– По-четим код