SlideShare une entreprise Scribd logo
1  sur  38
Télécharger pour lire hors ligne
Темы лекции: Делегаты, события, анонимные методы.
Практическое задание: Делегаты, события, анонимные методы.
Тренер: Игорь Шкулипа, к.т.н.
Платформа .Net и язык программирования C#.
Занятие 6
http://www.slideshare.net/IgorShkulipa 2
Делегаты
Делегаты являются ссылками на методы, инкапсулирующими настоящие
указатели и предоставляющими удобные сервисы для работы с ними.
Ссылки представляют собой объекты соответствующего типа. Все
делегаты являются объектами типа System.Delegate или
System.MulticastDelegate, который является наследником первого.
[SerializableAttribute]
[ClassInterfaceAttribute(ClassInterfaceType.AutoDual)]
[ComVisibleAttribute(true)]
public abstract class Delegate : ICloneable, ISerializable
[SerializableAttribute]
[ComVisibleAttribute(true)]
public abstract class MulticastDelegate : Delegate
Делегаты обеспечивают, поддерживаемый языком, механизм определения
и выполнения обратных вызовов.
В С++ есть аналог делегатов – это указатели на функции.
http://www.slideshare.net/IgorShkulipa 3
Создание и использование делегатов
public delegate double SomeDelegate(double x, double y);
Встречая такую конструкцию, компилятор автоматически генерирует
класс-наследник MulticastDelegate, автоматически реализуя все
необходимые методы. В частности, метод Invoke(), который, по сути, и
является вызовом делегата.
К делегатам можно привязывать как статичные методы класса, так и
методы конкретного экземпляра.
На практике, вызов делегата подобен вызову обычной функции.
public delegate Complex ComplAction(Complex c);
static void Main(string[] args)
{
Complex cc1 = new Complex(1, 2);
Complex cc2 = new Complex(2, 3);
ComplAction[] ca = new ComplAction[2];
ca[0] = cc1.Add;
ca[1] = cc1.Sub;
Console.WriteLine(ca[0](cc2).ToString());
Console.WriteLine(ca[1](cc2).ToString());
}
http://www.slideshare.net/IgorShkulipa 4
Класс Complex и объявление делегата
public class Complex : IComparable
{
public double Re { get; set; }
public double Im { get; set; }
// ... Конструкторы
public Complex Add(Complex right)
{
return new Complex(this.Re + right.Re, this.Im + right.Im);
}
public Complex Sub(Complex right)
{
return new Complex(this.Re - right.Re, this.Im - right.Im);
}
public void Print()
{
Console.WriteLine(this.ToString());
}
// Полное описание класса см. Презентацию № 3.
}
http://www.slideshare.net/IgorShkulipa 5
Цепочки делегатов
Цепочка делегатов позволяет создавать связный список делегатов так, чтобы, при
вызове первого делегата из списка, вызывались все остальные последовательно.
Для управления цепочками делегатов, класс System.Delegate предоставляет
следующие методы:
1. Для группирования делегатов в цепочки используется метод Combine()
public class Delegate: ICloneable, ISerializable
{
public static Delegate Combine(Delegate[] );
public static Delegate Combine(Delegate first, Delegate second);
}
2. Для удаления делегата из списка служат методы Remove и RemoveAll
public class Delegate: ICloneable, ISerializable
{
public static Delegate Remove(Delegate source, Delegate value );
public static Delegate RemoveAll(Delegate source, Delegate value );
}
Так же, для цепочек делегатов перегружены операции сложения (+) и вычитания (-),
обеспечивающие добавление и удаление делегата из списка.
http://www.slideshare.net/IgorShkulipa 6
Использование цепочек делегатов
public delegate void ComplPrint();
class Program
{
static void Main(string[] args)
{
Complex cc1 = new Complex(1, 2);
Complex cc2 = new Complex(2, 3);
Complex cc3 = new Complex(3, 4);
ComplPrint[] cp = new ComplPrint[3];
cp[0] = cc1.Print;
cp[1] = cc2.Print;
cp[2] = cc3.Print;
ComplPrint chainedDelegates = cp[0] + cp[1] + cp[2];
chainedDelegates();
Console.ReadKey();
}
}
}
1+i2
2+i3
3+i4
http://www.slideshare.net/IgorShkulipa 7
Итерация по цепочкам делегатов
Если требуется вызвать конкретный делегат из цепочки, или вызвать все делегаты в
определенной последовательности, то для этого, класс Delegate предоставляет
метод GetInvocationList(), который возвращает массив делегатов из цепочки.
public delegate void ComplPrint();
class Program {
static void Main(string[] args)
{
Complex cc1 = new Complex(1, 2);
Complex cc2 = new Complex(2, 3);
Complex cc3 = new Complex(3, 4);
ComplPrint[] cp = new ComplPrint[3];
cp[0] = cc1.Print;
cp[1] = cc2.Print;
cp[2] = cc3.Print;
ComplPrint chainedDelegates = cp[0] + cp[1] + cp[2];
Delegate[] delegateList = chainedDelegates.GetInvocationList();
for (int i = delegateList.Length - 1; i >= 0; i--) {
((ComplPrint)delegateList[i])();
}
Console.ReadKey();
}
}
3+i4
2+i3
1+i2
http://www.slideshare.net/IgorShkulipa 8
Делегаты открытого экземпляра
Делегаты открытого экземпляра (несвязанные делегаты) используются, когда необходимо,
чтобы делегат представлял метод определенного экземпляра, но вызывать этот метод
можно на целой коллекции экземпляров.
Класс MethodInfo выявляет атрибуты метода и обеспечивает доступ к его метаданным.
using System.Reflection;
public delegate void PrintAllComplex(Complex c);
class Program {
static void Main(string[] args) {
Complex cc1 = new Complex(1, 2); Complex cc2 = new Complex(2, 3);
Complex cc3 = new Complex(3, 4);
List<Complex> cl = new List<Complex>();
cl.Add(cc1); cl.Add(cc2); cl.Add(cc3);
// Создаем делегат открытого эезкмпляра
MethodInfo mi =
typeof(Complex).GetMethod("Print",
BindingFlags.Public | BindingFlags.Instance);
PrintAllComplex openDelegate =
(PrintAllComplex)Delegate.CreateDelegate(typeof(PrintAllComplex), mi);
foreach (var c in cl) {
openDelegate(c);
}
Console.ReadKey();
}
}
1+i2
2+i3
3+i4
http://www.slideshare.net/IgorShkulipa 9
Паттерн проектирования «Мост»
Используется для того, чтобы разделять абстракцию и реализацию так,
чтобы они могли изменяться независимо.
http://www.slideshare.net/IgorShkulipa 10
Реализация. Классы реализаторов с общим
интерфейсом
public interface Iimplementor {
void Operation();
}
class Implementor1 : Iimplementor {
void IImplementor.Operation() {
Console.WriteLine("Implementor 1");
}
}
class Implementor2 : Iimplementor {
void IImplementor.Operation() {
Console.WriteLine("Implementor 2");
}
}
http://www.slideshare.net/IgorShkulipa 11
Класс-абстракция
class Abstraction
{
protected IImplementor implementor;
public Abstraction() { }
public void SetImplementor(IImplementor implementor)
{
this.implementor = implementor;
}
public void Operation()
{
implementor.Operation();
}
}
http://www.slideshare.net/IgorShkulipa 12
Использование моста
class Program
{
static void Main(string[] args)
{
Abstraction abstr = new Abstraction();
abstr.SetImplementor(new Implementor1());
abstr.Operation();
abstr.SetImplementor(new Implementor2());
abstr.Operation();
Console.ReadKey();
}
}
Результат:
Implementor 1
Implementor 2
http://www.slideshare.net/IgorShkulipa 13
События
События позволяют классу или объекту уведомлять другие классы или
объекты о возникновении каких-либо ситуаций. Класс, отправляющий
(или вызывающий) событие, называется издателем, а классы,
принимающие (или обрабатывающие) событие, называются
подписчиками.
В C# в приложении Windows Forms или веб-приложении пользователь
подписывается на события, вызываемые элементами управления,
такими как кнопки и поля со списками.
С точки зрения синтаксиса объявления, события – это, по сути,
сокращение, которое избавляет от необходимости ручного создания
цепочек делегатов и регистрации делегатов в цепочках.
Делегат – указатель на метод.
Событие – указатель на несколько методов.
http://www.slideshare.net/IgorShkulipa 14
Свойства событий
События имеют следующие свойства:
• Издатель определяет момент вызова события, подписчики
определяют предпринятое ответное действие.
• У события может быть несколько подписчиков. Подписчик
может обрабатывать несколько событий от нескольких издателей.
• События, не имеющие подписчиков, никогда не возникают.
• Обычно события используются для оповещения о действиях
пользователя, таких как нажатия кнопок или выбор меню и их
пунктов в графическом пользовательском интерфейсе.
• Если событие имеет несколько подписчиков, то при его
возникновении происходит синхронный вызов обработчиков
событий.
• В библиотеке классов .NET Framework в основе событий лежит
делегат EventHandler и базовый класс EventArgs.
http://www.slideshare.net/IgorShkulipa 15
Пример: класс аргументов события
public class OnPowerOnArgs : EventArgs
{
public string DisplayText
{
get;
private set;
}
public OnPowerOnArgs(string strText)
{
DisplayText = strText;
}
}
http://www.slideshare.net/IgorShkulipa 16
Класс-издатель события
public class UserInterface
{
public event EventHandler<OnPowerOnArgs> OnPowerOn;
public UserInterface()
{
OnPowerOn += HandlePowerOn;
}
public void InitiatePowerOn(object sender, OnPowerOnArgs args)
{
OnPowerOn.Invoke(sender, args);
}
protected void HandlePowerOn(object sender, OnPowerOnArgs args)
{
Console.WriteLine(sender.ToString()+": "+args.DisplayText);
}
}
http://www.slideshare.net/IgorShkulipa 17
Класс-подписчик
public class User
{
static void Main(string[] args)
{
UserInterface ui = new UserInterface();
ui.InitiatePowerOn
("Vasiliy Pupkin", new OnPowerOnArgs("Power On"));
Console.ReadKey();
}
}
Vasiliy Pupkin: Power On
http://www.slideshare.net/IgorShkulipa 18
Паттерн Chain of Responsibility
Паттерн Chain of Responsibility позволяет избежать жесткой
зависимости отправителя запроса от его получателя, при этом
запрос может быть обработан несколькими объектами.
Объекты-получатели связываются в цепочку. Запрос
передается по этой цепочке, пока не будет обработан.
Вводит конвейерную обработку для запроса с множеством
возможных обработчиков.
Объектно-ориентированный связанный список с рекурсивным
обходом.
http://www.slideshare.net/IgorShkulipa 19
Общая схема паттерна
Клиент
Обработчик 1
Обработчик 2
Обработчик 3
Обработчик ...
Обработчик n
http://www.slideshare.net/IgorShkulipa 20
Реализация цепочки. Классы событий
public abstract class IEvent{
public string EventType { get; set; }
}
class Event1 : IEvent {
public Event1() { EventType = "Event1"; }
}
class Event2 : IEvent {
public Event2() { EventType = "Event2"; }
}
class Event3 : IEvent {
public Event3() { EventType = "Event3"; }
}
class Event4 : IEvent {
public Event4() { EventType = "Event4"; }
}
class Event5 : IEvent {
public Event5() { EventType = "Event5"; }
}
class Event6 : IEvent {
public Event6() { EventType = "Event6"; }
}
http://www.slideshare.net/IgorShkulipa 21
Базовый класс-обработчик
public abstract class BaseHandler {
public BaseHandler() { Next = null; }
public virtual void Handle(IEvent ev) {
if (PrivateEvent.EventType == ev.EventType)
{
Console.WriteLine("{0} successfully handled", PrivateEvent.EventType);
} else {
Console.WriteLine("Sending event to next Handler...");
if (Next != null)
Next.Handle(ev);
else
Console.WriteLine("Unknown event. Can't handle.");
}
}
protected void SetNextHandler(BaseHandler newHandler) {
Next = newHandler;
}
protected BaseHandler Next { get; set; }
protected IEvent PrivateEvent { get; set; }
}
http://www.slideshare.net/IgorShkulipa 22
Классы-обработчики
class Handler5 : BaseHandler {
public Handler5() {
PrivateEvent = new Event5(); Next = null;
} }
class Handler4 : BaseHandler {
public Handler4() {
PrivateEvent = new Event4(); Next = new Handler5();
} }
class Handler3 : BaseHandler {
public Handler3() {
PrivateEvent = new Event3(); Next = new Handler4();
} }
class Handler2 : BaseHandler {
public Handler2() {
PrivateEvent = new Event2(); Next = new Handler3();
} }
class Handler1 : BaseHandler {
public Handler1() {
PrivateEvent = new Event1(); Next = new Handler2();
} }
http://www.slideshare.net/IgorShkulipa 23
Класс тестового приложения
public class ChainApplication {
public ChainApplication() {
eventHandler = new Handler1(); Rand = new Random();
}
public void Run(int EventCount) {
for (int i = 0; i < EventCount; i++) {
HandleEvent(GenerateRandomEvent());
} }
private void HandleEvent(IEvent ev) {
eventHandler.Handle(ev);
}
private IEvent GenerateRandomEvent() {
IEvent result;
switch (Rand.Next(1,6)) {
case 0: result = new Event1(); break; case 1: result = new Event2(); break;
case 2: result = new Event3(); break; case 3: result = new Event4(); break;
case 4: result = new Event5(); break; default: result = new Event6(); break; }
Console.WriteLine("Generated event: {0}", result.EventType);
return result; }
private BaseHandler eventHandler;
private Random Rand;
}
http://www.slideshare.net/IgorShkulipa 24
Результат цепочки ответственностей
class Program
{
static void Main(string[] args)
{
ChainApplication app = new ChainApplication();
app.Run(3);
Console.ReadKey();
}
}
Результат:
Generated event: Event4
Sending event to next Handler...
Sending event to next Handler...
Sending event to next Handler...
Event4 successfully handled
Generated event: Event6
Sending event to next Handler...
Sending event to next Handler...
Sending event to next Handler...
Sending event to next Handler...
Sending event to next Handler...
Unknown event. Can't handle.
Generated event: Event5
Sending event to next Handler...
Sending event to next Handler...
Sending event to next Handler...
Sending event to next Handler...
Event5 successfully handled
http://www.slideshare.net/IgorShkulipa 25
Паттерн «Стратегия»
Паттерн Стратегия (Strategy) предназначен для определения
семейства алгоритмов и инкапсуляции каждого из них и
обеспечения их взаимозаменяемости.
Переносит в отдельную иерархию классов все детали, связанные
с реализацией алгоритмов.
http://www.slideshare.net/IgorShkulipa 26
Пример
public abstract class IStrategy
{
public abstract void Use();
protected void WakeUp() { Console.WriteLine("Wake up."); }
protected void Shower() { Console.WriteLine("Take shower."); }
protected void Dress() { Console.WriteLine("Dress."); }
protected void GoToBusStop() { Console.WriteLine("Go to bus stop."); }
protected void Wait() { Console.WriteLine("Wait."); }
protected void Arrive() { Console.WriteLine("Arrive."); }
protected void DoWork() { Console.WriteLine("Do work."); }
protected void DoExercises() { Console.WriteLine("Do exercises."); }
protected void Walk() { Console.WriteLine("Walk."); }
protected void GoOut() { Console.WriteLine("Go out."); }
protected void GoToPark() { Console.WriteLine("Go to park."); }
}
http://www.slideshare.net/IgorShkulipa 27
Классы конкретных стратегий
class GoToWorkStrategy : Istrategy {
public override void Use()
{
WakeUp(); Shower(); Dress(); GoOut();
GoToBusStop(); Wait(); Arrive(); DoWork();
}
}
class GoWalkStrategy : Istrategy {
public override void Use()
{
GoOut(); GoToPark(); Walk();
}
}
class GoToGymStrategy : Istrategy {
public override void Use()
{
GoOut(); GoToBusStop(); Arrive(); DoExercises();
}
}
http://www.slideshare.net/IgorShkulipa 28
Клиент стратегий
public abstract class IStrategyClient
{
public abstract void UseStrategy();
public void SetStrategy(IStrategy st) { strategy = st; }
protected IStrategy strategy;
}
class StrategyClient1 : IStrategyClient
{
public StrategyClient1() { }
public override void UseStrategy()
{
strategy.Use();
}
}
http://www.slideshare.net/IgorShkulipa 29
Использование стратегий
class Program
{
static void Main(string[] args)
{
IStrategyClient stClient = new StrategyClient1();
stClient.SetStrategy(new GoToWorkStrategy());
stClient.UseStrategy();
Console.WriteLine();
stClient.SetStrategy(new GoToGymStrategy());
stClient.UseStrategy();
Console.WriteLine();
stClient.SetStrategy(new GoWalkStrategy());
stClient.UseStrategy();
Console.ReadKey();
}
}
Wake up.
Take shower.
Dress.
Go out.
Go to bus stop.
Wait.
Arrive.
Do work.
Go out.
Go to bus stop.
Arrive.
Do exercises.
Go out.
Go to park.
Walk.
http://www.slideshare.net/IgorShkulipa 30
Анонимные методы
Новый класс стратегий:
public delegate void StrategyDelegate();
public abstract class IStrategyClient
{
public abstract void UseStrategy();
public StrategyDelegate Strategy { get; set; }
}
class StrategyClient1 : IStrategyClient
{
public StrategyClient1() { }
public override void UseStrategy()
{
Strategy();
}
}
http://www.slideshare.net/IgorShkulipa 31
Использование анонимных методов
class Program
{
static void Main(string[] args)
{
IStrategyClient stClient = new StrategyClient1();
IStrategy goWork = new GoToWorkStrategy();
IStrategy goGym = new GoToGymStrategy();
IStrategy goWalk = new GoWalkStrategy();
stClient.Strategy = delegate {
Console.WriteLine("Anonymous Method:");
goWork.Use();
Console.WriteLine(); };
stClient.UseStrategy();
stClient.Strategy = delegate {
Console.WriteLine("Anonymous Method:");
goGym.Use(); Console.WriteLine(); };
stClient.UseStrategy();
stClient.Strategy = delegate {
Console.WriteLine("Anonymous Method:");
goWalk.Use(); Console.WriteLine(); };
stClient.UseStrategy();
Console.ReadKey();
}
}
Anonymous Method:
Wake up.
Take shower.
Dress.
Go out.
Go to bus stop.
Wait.
Arrive.
Do work.
Anonymous Method:
Go out.
Go to bus stop.
Arrive.
Do exercises.
Anonymous Method:
Go out.
Go to park.
Walk.
http://www.slideshare.net/IgorShkulipa 32
Расширяющие методы
Расширяющие методы (методы расширения) позволяют "добавлять" методы в
существующие типы без создания нового производного типа, перекомпиляции или
иного изменения исходного типа.
Расширяющие методы являются особым видом статического метода, но они
вызываются, как если бы они были методами экземпляра в расширенном типе. Для
клиентского кода, написанного на языках C#, нет видимого различия между
вызовом метода расширения и вызовом методов, фактически определенных в типе.
public static class MyExtensions
{
public static int WordCount(this String str)
{
return str.Split(new char[] { ' ', '.', '?' },
StringSplitOptions.RemoveEmptyEntries).Length;
}
}
Методы расширения определяются как статические методы, но вызываются с
помощью синтаксиса обращения к методу экземпляра. Их первый параметр
определяет, с каким типом оперирует метод, и перед параметром идет
модификатор this. Методы расширения находятся в области действия, только если
пространство имен было явно импортировано в исходный код с помощью
директивы using.
http://www.slideshare.net/IgorShkulipa 33
Пример расширяющих методов
public static class ExtensionMethods
{
public static double Angle(this Complex compl)
{
if ((compl.Re == 0) && (compl.Im >= 0)) {
return Math.PI / 2;
}
if ((compl.Re == 0) && (compl.Im < 0)) {
return 3 * Math.PI / 2;
}
return Math.Atan(compl.Im / compl.Re);
}
}
class Program
{
static void Main(string[] args)
{
Complex c1 = new Complex(1,2);
Console.WriteLine(c1);
double angle = c1.Angle();
Console.WriteLine(angle);
Console.ReadKey();
}
}
http://www.slideshare.net/IgorShkulipa 34
Шаблон проектирования «Visitor»
Паттерн Visitor определяет операцию, выполняемую на каждом
элементе из некоторой структуры без изменения классов этих
объектов.
• Паттерн Visitor определяет операцию, выполняемую на каждом
элементе из некоторой структуры. Позволяет, не изменяя классы
этих объектов, добавлять в них новые операции.
Применение расширяющих методов значительно упрощает реализацию
этого паттерна.
http://www.slideshare.net/IgorShkulipa 35
Классы «компонентов»
public class SomeClass1
{
public SomeClass1(int c) { SomeProperty1 = c; }
public int SomeProperty1 { get; set; }
}
public class SomeClass2
{
public SomeClass2(int c) { SomeProperty2 = c; }
public int SomeProperty2 { get; set; }
}
public class SomeClass3
{
public SomeClass3(int c) { SomeProperty3 = c; }
public int SomeProperty3 { get; set; }
}
http://www.slideshare.net/IgorShkulipa 36
Класс-посетитель
public static class Visitor
{
public static void Visit(this SomeClass1 sc1)
{
Console.WriteLine(sc1.SomeProperty1);
}
public static void Visit(this SomeClass2 sc2)
{
Console.WriteLine(sc2.SomeProperty2);
}
public static void Visit(this SomeClass3 sc3)
{
Console.WriteLine(sc3.SomeProperty3);
}
}
http://www.slideshare.net/IgorShkulipa 37
Использование
class Program
{
static void Main(string[] args)
{
SomeClass1 c1 = new SomeClass1(1);
SomeClass2 c2 = new SomeClass2(2);
SomeClass3 c3 = new SomeClass3(3);
c1.Visit(); c2.Visit(); c3.Visit();
Console.ReadKey();
}
}
1
2
3
http://www.slideshare.net/IgorShkulipa 38
Лабораторная работа № 6. Делегаты, события
Используя класс «Квадратная матрица» из лабораторной работы №3,
реализовать тестовое приложение «Матричный калькулятор».
Добавить к классу расширяющие методы транспонирования матрицы и
нахождения следа матрицы (сумма диагональных элементов).
Создать делегат на основе анонимного метода приведения матрицы к
диагональному виду.
Реализовать меню для управления вычислений на основе делегатов с
использованием паттерна проектирования «Цепочка ответственности».

Contenu connexe

Tendances

работа с потоками ввода вывода
работа с потоками ввода выводаработа с потоками ввода вывода
работа с потоками ввода выводаmetaform
 
Глава 2: Среда разработки NetBeans
Глава 2: Среда разработки NetBeansГлава 2: Среда разработки NetBeans
Глава 2: Среда разработки NetBeansmetaform
 
8. java lecture threads
8. java lecture threads8. java lecture threads
8. java lecture threadsMERA_school
 
10. java lecture generics&collections
10. java lecture generics&collections10. java lecture generics&collections
10. java lecture generics&collectionsMERA_school
 
C# Desktop. Занятие 02.
C# Desktop. Занятие 02.C# Desktop. Занятие 02.
C# Desktop. Занятие 02.Igor Shkulipa
 
C# Desktop. Занятие 04.
C# Desktop. Занятие 04.C# Desktop. Занятие 04.
C# Desktop. Занятие 04.Igor Shkulipa
 
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.Igor Shkulipa
 
C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.Igor Shkulipa
 
Лекция 6_принципы ООП : инкапсуляция, наследование
Лекция 6_принципы ООП : инкапсуляция, наследованиеЛекция 6_принципы ООП : инкапсуляция, наследование
Лекция 6_принципы ООП : инкапсуляция, наследованиеmetaform
 
Java осень 2014 занятие 7
Java осень 2014 занятие 7Java осень 2014 занятие 7
Java осень 2014 занятие 7Technopark
 
Java осень 2014 занятие 6
Java осень 2014 занятие 6Java осень 2014 занятие 6
Java осень 2014 занятие 6Technopark
 
05 - Java. Collections Framework и Generics
05 - Java. Collections Framework и Generics05 - Java. Collections Framework и Generics
05 - Java. Collections Framework и GenericsRoman Brovko
 
Клиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталяхКлиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталяхKirill Zotin
 
Создание графического интерфейса пользователя мобильных Android приложений (ч...
Создание графического интерфейса пользователя мобильных Android приложений (ч...Создание графического интерфейса пользователя мобильных Android приложений (ч...
Создание графического интерфейса пользователя мобильных Android приложений (ч...metaform
 

Tendances (14)

работа с потоками ввода вывода
работа с потоками ввода выводаработа с потоками ввода вывода
работа с потоками ввода вывода
 
Глава 2: Среда разработки NetBeans
Глава 2: Среда разработки NetBeansГлава 2: Среда разработки NetBeans
Глава 2: Среда разработки NetBeans
 
8. java lecture threads
8. java lecture threads8. java lecture threads
8. java lecture threads
 
10. java lecture generics&collections
10. java lecture generics&collections10. java lecture generics&collections
10. java lecture generics&collections
 
C# Desktop. Занятие 02.
C# Desktop. Занятие 02.C# Desktop. Занятие 02.
C# Desktop. Занятие 02.
 
C# Desktop. Занятие 04.
C# Desktop. Занятие 04.C# Desktop. Занятие 04.
C# Desktop. Занятие 04.
 
C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.C++ STL & Qt. Занятие 04.
C++ STL & Qt. Занятие 04.
 
C# Desktop. Занятие 01.
C# Desktop. Занятие 01.C# Desktop. Занятие 01.
C# Desktop. Занятие 01.
 
Лекция 6_принципы ООП : инкапсуляция, наследование
Лекция 6_принципы ООП : инкапсуляция, наследованиеЛекция 6_принципы ООП : инкапсуляция, наследование
Лекция 6_принципы ООП : инкапсуляция, наследование
 
Java осень 2014 занятие 7
Java осень 2014 занятие 7Java осень 2014 занятие 7
Java осень 2014 занятие 7
 
Java осень 2014 занятие 6
Java осень 2014 занятие 6Java осень 2014 занятие 6
Java осень 2014 занятие 6
 
05 - Java. Collections Framework и Generics
05 - Java. Collections Framework и Generics05 - Java. Collections Framework и Generics
05 - Java. Collections Framework и Generics
 
Клиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталяхКлиент-серверное взаимодействие под android в деталях
Клиент-серверное взаимодействие под android в деталях
 
Создание графического интерфейса пользователя мобильных Android приложений (ч...
Создание графического интерфейса пользователя мобильных Android приложений (ч...Создание графического интерфейса пользователя мобильных Android приложений (ч...
Создание графического интерфейса пользователя мобильных Android приложений (ч...
 

En vedette

C# Desktop. Занятие 11.
C# Desktop. Занятие 11.C# Desktop. Занятие 11.
C# Desktop. Занятие 11.Igor Shkulipa
 
Advanced LinkedIn Techniques
Advanced LinkedIn TechniquesAdvanced LinkedIn Techniques
Advanced LinkedIn TechniquesJames Weber
 
C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.Igor Shkulipa
 
C++ Базовый. Занятие 08.
C++ Базовый. Занятие 08.C++ Базовый. Занятие 08.
C++ Базовый. Занятие 08.Igor Shkulipa
 
Production diary 15
Production diary 15Production diary 15
Production diary 15Laila Jaleel
 
Production diary 9
Production diary 9Production diary 9
Production diary 9Laila Jaleel
 
C++ Базовый. Занятие 04.
C++ Базовый. Занятие 04.C++ Базовый. Занятие 04.
C++ Базовый. Занятие 04.Igor Shkulipa
 
JavaScript Базовый. Занятие 05.
JavaScript Базовый. Занятие 05.JavaScript Базовый. Занятие 05.
JavaScript Базовый. Занятие 05.Igor Shkulipa
 
Laura mulvey’s male gaze theory
Laura mulvey’s male gaze theoryLaura mulvey’s male gaze theory
Laura mulvey’s male gaze theoryLaila Jaleel
 
JavaScript Базовый. Занятие 01.
JavaScript Базовый. Занятие 01.JavaScript Базовый. Занятие 01.
JavaScript Базовый. Занятие 01.Igor Shkulipa
 
C# Web. Занятие 15.
C# Web. Занятие 15.C# Web. Занятие 15.
C# Web. Занятие 15.Igor Shkulipa
 
Trabajo completo correcion
Trabajo completo correcionTrabajo completo correcion
Trabajo completo correcionIda Morán
 
Общие темы. Тема 02.
Общие темы. Тема 02.Общие темы. Тема 02.
Общие темы. Тема 02.Igor Shkulipa
 
Company | How it works
Company | How it worksCompany | How it works
Company | How it worksGREXdotIN
 

En vedette (20)

C# Desktop. Занятие 11.
C# Desktop. Занятие 11.C# Desktop. Занятие 11.
C# Desktop. Занятие 11.
 
Your Five Senses
Your Five SensesYour Five Senses
Your Five Senses
 
Truly Verona
Truly VeronaTruly Verona
Truly Verona
 
Advanced LinkedIn Techniques
Advanced LinkedIn TechniquesAdvanced LinkedIn Techniques
Advanced LinkedIn Techniques
 
C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.C++ STL & Qt. Занятие 08.
C++ STL & Qt. Занятие 08.
 
C++ Базовый. Занятие 08.
C++ Базовый. Занятие 08.C++ Базовый. Занятие 08.
C++ Базовый. Занятие 08.
 
Production diary 15
Production diary 15Production diary 15
Production diary 15
 
Production diary 9
Production diary 9Production diary 9
Production diary 9
 
C++ Базовый. Занятие 04.
C++ Базовый. Занятие 04.C++ Базовый. Занятие 04.
C++ Базовый. Занятие 04.
 
JavaScript Базовый. Занятие 05.
JavaScript Базовый. Занятие 05.JavaScript Базовый. Занятие 05.
JavaScript Базовый. Занятие 05.
 
PRES Eve's Dream
PRES Eve's DreamPRES Eve's Dream
PRES Eve's Dream
 
5 niveles de prevension
5  niveles de prevension5  niveles de prevension
5 niveles de prevension
 
SAEEDcv.
SAEEDcv.SAEEDcv.
SAEEDcv.
 
Laura mulvey’s male gaze theory
Laura mulvey’s male gaze theoryLaura mulvey’s male gaze theory
Laura mulvey’s male gaze theory
 
JavaScript Базовый. Занятие 01.
JavaScript Базовый. Занятие 01.JavaScript Базовый. Занятие 01.
JavaScript Базовый. Занятие 01.
 
What is Lean UX?
What is Lean UX?What is Lean UX?
What is Lean UX?
 
C# Web. Занятие 15.
C# Web. Занятие 15.C# Web. Занятие 15.
C# Web. Занятие 15.
 
Trabajo completo correcion
Trabajo completo correcionTrabajo completo correcion
Trabajo completo correcion
 
Общие темы. Тема 02.
Общие темы. Тема 02.Общие темы. Тема 02.
Общие темы. Тема 02.
 
Company | How it works
Company | How it worksCompany | How it works
Company | How it works
 

Similaire à C# Desktop. Занятие 06.

паттерны программирования
паттерны программированияпаттерны программирования
паттерны программированияguestfc8ae0
 
Lec 2 Java
Lec 2 JavaLec 2 Java
Lec 2 Javaitc73
 
C# Desktop. Занятие 07.
C# Desktop. Занятие 07.C# Desktop. Занятие 07.
C# Desktop. Занятие 07.Igor Shkulipa
 
Михаил Щербаков «Что может быть проще: делегаты и события»
Михаил Щербаков «Что может быть проще: делегаты и события»Михаил Щербаков «Что может быть проще: делегаты и события»
Михаил Щербаков «Что может быть проще: делегаты и события»SpbDotNet Community
 
Java весна 2013 лекция 9
Java весна 2013 лекция 9Java весна 2013 лекция 9
Java весна 2013 лекция 9Technopark
 
Mikhail Valkov_Antipatterns
Mikhail Valkov_AntipatternsMikhail Valkov_Antipatterns
Mikhail Valkov_AntipatternsCiklum
 
Lambdas in java 8
Lambdas in java 8Lambdas in java 8
Lambdas in java 8chashnikov
 
Java осень 2012 лекция 9
Java осень 2012 лекция 9Java осень 2012 лекция 9
Java осень 2012 лекция 9Technopark
 
C++ осень 2013 лекция 4
C++ осень 2013 лекция 4C++ осень 2013 лекция 4
C++ осень 2013 лекция 4Technopark
 
C++ осень 2012 лекция 9
C++ осень 2012 лекция 9C++ осень 2012 лекция 9
C++ осень 2012 лекция 9Technopark
 
C# Web. Занятие 10.
C# Web. Занятие 10.C# Web. Занятие 10.
C# Web. Занятие 10.Igor Shkulipa
 
Веселая ферма. Соседи.
Веселая ферма. Соседи.Веселая ферма. Соседи.
Веселая ферма. Соседи.Doomer Samoiloff
 
C++ Базовый. Занятие 09.
C++ Базовый. Занятие 09.C++ Базовый. Занятие 09.
C++ Базовый. Занятие 09.Igor Shkulipa
 
Лекция 6
Лекция 6Лекция 6
Лекция 6itc73
 
C# Desktop. Занятие 16.
C# Desktop. Занятие 16.C# Desktop. Занятие 16.
C# Desktop. Занятие 16.Igor Shkulipa
 
Java осень 2013 лекция 6
Java осень 2013 лекция 6Java осень 2013 лекция 6
Java осень 2013 лекция 6Technopark
 

Similaire à C# Desktop. Занятие 06. (20)

паттерны программирования
паттерны программированияпаттерны программирования
паттерны программирования
 
Lec 2
Lec 2Lec 2
Lec 2
 
Lec 2 Java
Lec 2 JavaLec 2 Java
Lec 2 Java
 
Delegates and events in C#
Delegates and events in C#Delegates and events in C#
Delegates and events in C#
 
Особенности C#
Особенности C#Особенности C#
Особенности C#
 
C# Desktop. Занятие 07.
C# Desktop. Занятие 07.C# Desktop. Занятие 07.
C# Desktop. Занятие 07.
 
Михаил Щербаков «Что может быть проще: делегаты и события»
Михаил Щербаков «Что может быть проще: делегаты и события»Михаил Щербаков «Что может быть проще: делегаты и события»
Михаил Щербаков «Что может быть проще: делегаты и события»
 
Java весна 2013 лекция 9
Java весна 2013 лекция 9Java весна 2013 лекция 9
Java весна 2013 лекция 9
 
Mikhail Valkov_Antipatterns
Mikhail Valkov_AntipatternsMikhail Valkov_Antipatterns
Mikhail Valkov_Antipatterns
 
Lambdas in java 8
Lambdas in java 8Lambdas in java 8
Lambdas in java 8
 
Java осень 2012 лекция 9
Java осень 2012 лекция 9Java осень 2012 лекция 9
Java осень 2012 лекция 9
 
C++ осень 2013 лекция 4
C++ осень 2013 лекция 4C++ осень 2013 лекция 4
C++ осень 2013 лекция 4
 
C++ осень 2012 лекция 9
C++ осень 2012 лекция 9C++ осень 2012 лекция 9
C++ осень 2012 лекция 9
 
C# Web. Занятие 10.
C# Web. Занятие 10.C# Web. Занятие 10.
C# Web. Занятие 10.
 
Веселая ферма. Соседи.
Веселая ферма. Соседи.Веселая ферма. Соседи.
Веселая ферма. Соседи.
 
C++ Базовый. Занятие 09.
C++ Базовый. Занятие 09.C++ Базовый. Занятие 09.
C++ Базовый. Занятие 09.
 
Лекция 6
Лекция 6Лекция 6
Лекция 6
 
C# Desktop. Занятие 16.
C# Desktop. Занятие 16.C# Desktop. Занятие 16.
C# Desktop. Занятие 16.
 
Java осень 2013 лекция 6
Java осень 2013 лекция 6Java осень 2013 лекция 6
Java осень 2013 лекция 6
 
Step 3.2
Step 3.2Step 3.2
Step 3.2
 

Plus de Igor Shkulipa

Общие темы. Тема 03.
Общие темы. Тема 03. Общие темы. Тема 03.
Общие темы. Тема 03. Igor Shkulipa
 
Общие темы. Тема 01.
Общие темы. Тема 01.Общие темы. Тема 01.
Общие темы. Тема 01.Igor Shkulipa
 
JavaScript Базовый. Занятие 06.
JavaScript Базовый. Занятие 06.JavaScript Базовый. Занятие 06.
JavaScript Базовый. Занятие 06.Igor Shkulipa
 
JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.Igor Shkulipa
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.Igor Shkulipa
 
JavaScript Базовый. Занятие 10.
JavaScript Базовый. Занятие 10.JavaScript Базовый. Занятие 10.
JavaScript Базовый. Занятие 10.Igor Shkulipa
 
JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.Igor Shkulipa
 
JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.Igor Shkulipa
 
JavaScript Базовый. Занятие 04.
JavaScript Базовый. Занятие 04.JavaScript Базовый. Занятие 04.
JavaScript Базовый. Занятие 04.Igor Shkulipa
 
JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.Igor Shkulipa
 
JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.Igor Shkulipa
 
C# Web. Занятие 09.
C# Web. Занятие 09.C# Web. Занятие 09.
C# Web. Занятие 09.Igor Shkulipa
 
C# Web. Занятие 08.
C# Web. Занятие 08.C# Web. Занятие 08.
C# Web. Занятие 08.Igor Shkulipa
 
C# Web. Занятие 07.
C# Web. Занятие 07.C# Web. Занятие 07.
C# Web. Занятие 07.Igor Shkulipa
 
C# Web. Занятие 04.
C# Web. Занятие 04.C# Web. Занятие 04.
C# Web. Занятие 04.Igor Shkulipa
 
C# Web. Занятие 12.
C# Web. Занятие 12.C# Web. Занятие 12.
C# Web. Занятие 12.Igor Shkulipa
 
C# Web. Занятие 16.
C# Web. Занятие 16.C# Web. Занятие 16.
C# Web. Занятие 16.Igor Shkulipa
 
C# Web. Занятие 14.
C# Web. Занятие 14.C# Web. Занятие 14.
C# Web. Занятие 14.Igor Shkulipa
 
C# Web. Занятие 13.
C# Web. Занятие 13.C# Web. Занятие 13.
C# Web. Занятие 13.Igor Shkulipa
 
C# Web. Занятие 11.
C# Web. Занятие 11.C# Web. Занятие 11.
C# Web. Занятие 11.Igor Shkulipa
 

Plus de Igor Shkulipa (20)

Общие темы. Тема 03.
Общие темы. Тема 03. Общие темы. Тема 03.
Общие темы. Тема 03.
 
Общие темы. Тема 01.
Общие темы. Тема 01.Общие темы. Тема 01.
Общие темы. Тема 01.
 
JavaScript Базовый. Занятие 06.
JavaScript Базовый. Занятие 06.JavaScript Базовый. Занятие 06.
JavaScript Базовый. Занятие 06.
 
JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.JavaScript Базовый. Занятие 11.
JavaScript Базовый. Занятие 11.
 
JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.JavaScript Базовый. Занятие 09.
JavaScript Базовый. Занятие 09.
 
JavaScript Базовый. Занятие 10.
JavaScript Базовый. Занятие 10.JavaScript Базовый. Занятие 10.
JavaScript Базовый. Занятие 10.
 
JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.JavaScript Базовый. Занятие 08.
JavaScript Базовый. Занятие 08.
 
JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.JavaScript Базовый. Занятие 07.
JavaScript Базовый. Занятие 07.
 
JavaScript Базовый. Занятие 04.
JavaScript Базовый. Занятие 04.JavaScript Базовый. Занятие 04.
JavaScript Базовый. Занятие 04.
 
JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.JavaScript Базовый. Занятие 03.
JavaScript Базовый. Занятие 03.
 
JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.JavaScript Базовый. Занятие 02.
JavaScript Базовый. Занятие 02.
 
C# Web. Занятие 09.
C# Web. Занятие 09.C# Web. Занятие 09.
C# Web. Занятие 09.
 
C# Web. Занятие 08.
C# Web. Занятие 08.C# Web. Занятие 08.
C# Web. Занятие 08.
 
C# Web. Занятие 07.
C# Web. Занятие 07.C# Web. Занятие 07.
C# Web. Занятие 07.
 
C# Web. Занятие 04.
C# Web. Занятие 04.C# Web. Занятие 04.
C# Web. Занятие 04.
 
C# Web. Занятие 12.
C# Web. Занятие 12.C# Web. Занятие 12.
C# Web. Занятие 12.
 
C# Web. Занятие 16.
C# Web. Занятие 16.C# Web. Занятие 16.
C# Web. Занятие 16.
 
C# Web. Занятие 14.
C# Web. Занятие 14.C# Web. Занятие 14.
C# Web. Занятие 14.
 
C# Web. Занятие 13.
C# Web. Занятие 13.C# Web. Занятие 13.
C# Web. Занятие 13.
 
C# Web. Занятие 11.
C# Web. Занятие 11.C# Web. Занятие 11.
C# Web. Занятие 11.
 

C# Desktop. Занятие 06.

  • 1. Темы лекции: Делегаты, события, анонимные методы. Практическое задание: Делегаты, события, анонимные методы. Тренер: Игорь Шкулипа, к.т.н. Платформа .Net и язык программирования C#. Занятие 6
  • 2. http://www.slideshare.net/IgorShkulipa 2 Делегаты Делегаты являются ссылками на методы, инкапсулирующими настоящие указатели и предоставляющими удобные сервисы для работы с ними. Ссылки представляют собой объекты соответствующего типа. Все делегаты являются объектами типа System.Delegate или System.MulticastDelegate, который является наследником первого. [SerializableAttribute] [ClassInterfaceAttribute(ClassInterfaceType.AutoDual)] [ComVisibleAttribute(true)] public abstract class Delegate : ICloneable, ISerializable [SerializableAttribute] [ComVisibleAttribute(true)] public abstract class MulticastDelegate : Delegate Делегаты обеспечивают, поддерживаемый языком, механизм определения и выполнения обратных вызовов. В С++ есть аналог делегатов – это указатели на функции.
  • 3. http://www.slideshare.net/IgorShkulipa 3 Создание и использование делегатов public delegate double SomeDelegate(double x, double y); Встречая такую конструкцию, компилятор автоматически генерирует класс-наследник MulticastDelegate, автоматически реализуя все необходимые методы. В частности, метод Invoke(), который, по сути, и является вызовом делегата. К делегатам можно привязывать как статичные методы класса, так и методы конкретного экземпляра. На практике, вызов делегата подобен вызову обычной функции. public delegate Complex ComplAction(Complex c); static void Main(string[] args) { Complex cc1 = new Complex(1, 2); Complex cc2 = new Complex(2, 3); ComplAction[] ca = new ComplAction[2]; ca[0] = cc1.Add; ca[1] = cc1.Sub; Console.WriteLine(ca[0](cc2).ToString()); Console.WriteLine(ca[1](cc2).ToString()); }
  • 4. http://www.slideshare.net/IgorShkulipa 4 Класс Complex и объявление делегата public class Complex : IComparable { public double Re { get; set; } public double Im { get; set; } // ... Конструкторы public Complex Add(Complex right) { return new Complex(this.Re + right.Re, this.Im + right.Im); } public Complex Sub(Complex right) { return new Complex(this.Re - right.Re, this.Im - right.Im); } public void Print() { Console.WriteLine(this.ToString()); } // Полное описание класса см. Презентацию № 3. }
  • 5. http://www.slideshare.net/IgorShkulipa 5 Цепочки делегатов Цепочка делегатов позволяет создавать связный список делегатов так, чтобы, при вызове первого делегата из списка, вызывались все остальные последовательно. Для управления цепочками делегатов, класс System.Delegate предоставляет следующие методы: 1. Для группирования делегатов в цепочки используется метод Combine() public class Delegate: ICloneable, ISerializable { public static Delegate Combine(Delegate[] ); public static Delegate Combine(Delegate first, Delegate second); } 2. Для удаления делегата из списка служат методы Remove и RemoveAll public class Delegate: ICloneable, ISerializable { public static Delegate Remove(Delegate source, Delegate value ); public static Delegate RemoveAll(Delegate source, Delegate value ); } Так же, для цепочек делегатов перегружены операции сложения (+) и вычитания (-), обеспечивающие добавление и удаление делегата из списка.
  • 6. http://www.slideshare.net/IgorShkulipa 6 Использование цепочек делегатов public delegate void ComplPrint(); class Program { static void Main(string[] args) { Complex cc1 = new Complex(1, 2); Complex cc2 = new Complex(2, 3); Complex cc3 = new Complex(3, 4); ComplPrint[] cp = new ComplPrint[3]; cp[0] = cc1.Print; cp[1] = cc2.Print; cp[2] = cc3.Print; ComplPrint chainedDelegates = cp[0] + cp[1] + cp[2]; chainedDelegates(); Console.ReadKey(); } } } 1+i2 2+i3 3+i4
  • 7. http://www.slideshare.net/IgorShkulipa 7 Итерация по цепочкам делегатов Если требуется вызвать конкретный делегат из цепочки, или вызвать все делегаты в определенной последовательности, то для этого, класс Delegate предоставляет метод GetInvocationList(), который возвращает массив делегатов из цепочки. public delegate void ComplPrint(); class Program { static void Main(string[] args) { Complex cc1 = new Complex(1, 2); Complex cc2 = new Complex(2, 3); Complex cc3 = new Complex(3, 4); ComplPrint[] cp = new ComplPrint[3]; cp[0] = cc1.Print; cp[1] = cc2.Print; cp[2] = cc3.Print; ComplPrint chainedDelegates = cp[0] + cp[1] + cp[2]; Delegate[] delegateList = chainedDelegates.GetInvocationList(); for (int i = delegateList.Length - 1; i >= 0; i--) { ((ComplPrint)delegateList[i])(); } Console.ReadKey(); } } 3+i4 2+i3 1+i2
  • 8. http://www.slideshare.net/IgorShkulipa 8 Делегаты открытого экземпляра Делегаты открытого экземпляра (несвязанные делегаты) используются, когда необходимо, чтобы делегат представлял метод определенного экземпляра, но вызывать этот метод можно на целой коллекции экземпляров. Класс MethodInfo выявляет атрибуты метода и обеспечивает доступ к его метаданным. using System.Reflection; public delegate void PrintAllComplex(Complex c); class Program { static void Main(string[] args) { Complex cc1 = new Complex(1, 2); Complex cc2 = new Complex(2, 3); Complex cc3 = new Complex(3, 4); List<Complex> cl = new List<Complex>(); cl.Add(cc1); cl.Add(cc2); cl.Add(cc3); // Создаем делегат открытого эезкмпляра MethodInfo mi = typeof(Complex).GetMethod("Print", BindingFlags.Public | BindingFlags.Instance); PrintAllComplex openDelegate = (PrintAllComplex)Delegate.CreateDelegate(typeof(PrintAllComplex), mi); foreach (var c in cl) { openDelegate(c); } Console.ReadKey(); } } 1+i2 2+i3 3+i4
  • 9. http://www.slideshare.net/IgorShkulipa 9 Паттерн проектирования «Мост» Используется для того, чтобы разделять абстракцию и реализацию так, чтобы они могли изменяться независимо.
  • 10. http://www.slideshare.net/IgorShkulipa 10 Реализация. Классы реализаторов с общим интерфейсом public interface Iimplementor { void Operation(); } class Implementor1 : Iimplementor { void IImplementor.Operation() { Console.WriteLine("Implementor 1"); } } class Implementor2 : Iimplementor { void IImplementor.Operation() { Console.WriteLine("Implementor 2"); } }
  • 11. http://www.slideshare.net/IgorShkulipa 11 Класс-абстракция class Abstraction { protected IImplementor implementor; public Abstraction() { } public void SetImplementor(IImplementor implementor) { this.implementor = implementor; } public void Operation() { implementor.Operation(); } }
  • 12. http://www.slideshare.net/IgorShkulipa 12 Использование моста class Program { static void Main(string[] args) { Abstraction abstr = new Abstraction(); abstr.SetImplementor(new Implementor1()); abstr.Operation(); abstr.SetImplementor(new Implementor2()); abstr.Operation(); Console.ReadKey(); } } Результат: Implementor 1 Implementor 2
  • 13. http://www.slideshare.net/IgorShkulipa 13 События События позволяют классу или объекту уведомлять другие классы или объекты о возникновении каких-либо ситуаций. Класс, отправляющий (или вызывающий) событие, называется издателем, а классы, принимающие (или обрабатывающие) событие, называются подписчиками. В C# в приложении Windows Forms или веб-приложении пользователь подписывается на события, вызываемые элементами управления, такими как кнопки и поля со списками. С точки зрения синтаксиса объявления, события – это, по сути, сокращение, которое избавляет от необходимости ручного создания цепочек делегатов и регистрации делегатов в цепочках. Делегат – указатель на метод. Событие – указатель на несколько методов.
  • 14. http://www.slideshare.net/IgorShkulipa 14 Свойства событий События имеют следующие свойства: • Издатель определяет момент вызова события, подписчики определяют предпринятое ответное действие. • У события может быть несколько подписчиков. Подписчик может обрабатывать несколько событий от нескольких издателей. • События, не имеющие подписчиков, никогда не возникают. • Обычно события используются для оповещения о действиях пользователя, таких как нажатия кнопок или выбор меню и их пунктов в графическом пользовательском интерфейсе. • Если событие имеет несколько подписчиков, то при его возникновении происходит синхронный вызов обработчиков событий. • В библиотеке классов .NET Framework в основе событий лежит делегат EventHandler и базовый класс EventArgs.
  • 15. http://www.slideshare.net/IgorShkulipa 15 Пример: класс аргументов события public class OnPowerOnArgs : EventArgs { public string DisplayText { get; private set; } public OnPowerOnArgs(string strText) { DisplayText = strText; } }
  • 16. http://www.slideshare.net/IgorShkulipa 16 Класс-издатель события public class UserInterface { public event EventHandler<OnPowerOnArgs> OnPowerOn; public UserInterface() { OnPowerOn += HandlePowerOn; } public void InitiatePowerOn(object sender, OnPowerOnArgs args) { OnPowerOn.Invoke(sender, args); } protected void HandlePowerOn(object sender, OnPowerOnArgs args) { Console.WriteLine(sender.ToString()+": "+args.DisplayText); } }
  • 17. http://www.slideshare.net/IgorShkulipa 17 Класс-подписчик public class User { static void Main(string[] args) { UserInterface ui = new UserInterface(); ui.InitiatePowerOn ("Vasiliy Pupkin", new OnPowerOnArgs("Power On")); Console.ReadKey(); } } Vasiliy Pupkin: Power On
  • 18. http://www.slideshare.net/IgorShkulipa 18 Паттерн Chain of Responsibility Паттерн Chain of Responsibility позволяет избежать жесткой зависимости отправителя запроса от его получателя, при этом запрос может быть обработан несколькими объектами. Объекты-получатели связываются в цепочку. Запрос передается по этой цепочке, пока не будет обработан. Вводит конвейерную обработку для запроса с множеством возможных обработчиков. Объектно-ориентированный связанный список с рекурсивным обходом.
  • 19. http://www.slideshare.net/IgorShkulipa 19 Общая схема паттерна Клиент Обработчик 1 Обработчик 2 Обработчик 3 Обработчик ... Обработчик n
  • 20. http://www.slideshare.net/IgorShkulipa 20 Реализация цепочки. Классы событий public abstract class IEvent{ public string EventType { get; set; } } class Event1 : IEvent { public Event1() { EventType = "Event1"; } } class Event2 : IEvent { public Event2() { EventType = "Event2"; } } class Event3 : IEvent { public Event3() { EventType = "Event3"; } } class Event4 : IEvent { public Event4() { EventType = "Event4"; } } class Event5 : IEvent { public Event5() { EventType = "Event5"; } } class Event6 : IEvent { public Event6() { EventType = "Event6"; } }
  • 21. http://www.slideshare.net/IgorShkulipa 21 Базовый класс-обработчик public abstract class BaseHandler { public BaseHandler() { Next = null; } public virtual void Handle(IEvent ev) { if (PrivateEvent.EventType == ev.EventType) { Console.WriteLine("{0} successfully handled", PrivateEvent.EventType); } else { Console.WriteLine("Sending event to next Handler..."); if (Next != null) Next.Handle(ev); else Console.WriteLine("Unknown event. Can't handle."); } } protected void SetNextHandler(BaseHandler newHandler) { Next = newHandler; } protected BaseHandler Next { get; set; } protected IEvent PrivateEvent { get; set; } }
  • 22. http://www.slideshare.net/IgorShkulipa 22 Классы-обработчики class Handler5 : BaseHandler { public Handler5() { PrivateEvent = new Event5(); Next = null; } } class Handler4 : BaseHandler { public Handler4() { PrivateEvent = new Event4(); Next = new Handler5(); } } class Handler3 : BaseHandler { public Handler3() { PrivateEvent = new Event3(); Next = new Handler4(); } } class Handler2 : BaseHandler { public Handler2() { PrivateEvent = new Event2(); Next = new Handler3(); } } class Handler1 : BaseHandler { public Handler1() { PrivateEvent = new Event1(); Next = new Handler2(); } }
  • 23. http://www.slideshare.net/IgorShkulipa 23 Класс тестового приложения public class ChainApplication { public ChainApplication() { eventHandler = new Handler1(); Rand = new Random(); } public void Run(int EventCount) { for (int i = 0; i < EventCount; i++) { HandleEvent(GenerateRandomEvent()); } } private void HandleEvent(IEvent ev) { eventHandler.Handle(ev); } private IEvent GenerateRandomEvent() { IEvent result; switch (Rand.Next(1,6)) { case 0: result = new Event1(); break; case 1: result = new Event2(); break; case 2: result = new Event3(); break; case 3: result = new Event4(); break; case 4: result = new Event5(); break; default: result = new Event6(); break; } Console.WriteLine("Generated event: {0}", result.EventType); return result; } private BaseHandler eventHandler; private Random Rand; }
  • 24. http://www.slideshare.net/IgorShkulipa 24 Результат цепочки ответственностей class Program { static void Main(string[] args) { ChainApplication app = new ChainApplication(); app.Run(3); Console.ReadKey(); } } Результат: Generated event: Event4 Sending event to next Handler... Sending event to next Handler... Sending event to next Handler... Event4 successfully handled Generated event: Event6 Sending event to next Handler... Sending event to next Handler... Sending event to next Handler... Sending event to next Handler... Sending event to next Handler... Unknown event. Can't handle. Generated event: Event5 Sending event to next Handler... Sending event to next Handler... Sending event to next Handler... Sending event to next Handler... Event5 successfully handled
  • 25. http://www.slideshare.net/IgorShkulipa 25 Паттерн «Стратегия» Паттерн Стратегия (Strategy) предназначен для определения семейства алгоритмов и инкапсуляции каждого из них и обеспечения их взаимозаменяемости. Переносит в отдельную иерархию классов все детали, связанные с реализацией алгоритмов.
  • 26. http://www.slideshare.net/IgorShkulipa 26 Пример public abstract class IStrategy { public abstract void Use(); protected void WakeUp() { Console.WriteLine("Wake up."); } protected void Shower() { Console.WriteLine("Take shower."); } protected void Dress() { Console.WriteLine("Dress."); } protected void GoToBusStop() { Console.WriteLine("Go to bus stop."); } protected void Wait() { Console.WriteLine("Wait."); } protected void Arrive() { Console.WriteLine("Arrive."); } protected void DoWork() { Console.WriteLine("Do work."); } protected void DoExercises() { Console.WriteLine("Do exercises."); } protected void Walk() { Console.WriteLine("Walk."); } protected void GoOut() { Console.WriteLine("Go out."); } protected void GoToPark() { Console.WriteLine("Go to park."); } }
  • 27. http://www.slideshare.net/IgorShkulipa 27 Классы конкретных стратегий class GoToWorkStrategy : Istrategy { public override void Use() { WakeUp(); Shower(); Dress(); GoOut(); GoToBusStop(); Wait(); Arrive(); DoWork(); } } class GoWalkStrategy : Istrategy { public override void Use() { GoOut(); GoToPark(); Walk(); } } class GoToGymStrategy : Istrategy { public override void Use() { GoOut(); GoToBusStop(); Arrive(); DoExercises(); } }
  • 28. http://www.slideshare.net/IgorShkulipa 28 Клиент стратегий public abstract class IStrategyClient { public abstract void UseStrategy(); public void SetStrategy(IStrategy st) { strategy = st; } protected IStrategy strategy; } class StrategyClient1 : IStrategyClient { public StrategyClient1() { } public override void UseStrategy() { strategy.Use(); } }
  • 29. http://www.slideshare.net/IgorShkulipa 29 Использование стратегий class Program { static void Main(string[] args) { IStrategyClient stClient = new StrategyClient1(); stClient.SetStrategy(new GoToWorkStrategy()); stClient.UseStrategy(); Console.WriteLine(); stClient.SetStrategy(new GoToGymStrategy()); stClient.UseStrategy(); Console.WriteLine(); stClient.SetStrategy(new GoWalkStrategy()); stClient.UseStrategy(); Console.ReadKey(); } } Wake up. Take shower. Dress. Go out. Go to bus stop. Wait. Arrive. Do work. Go out. Go to bus stop. Arrive. Do exercises. Go out. Go to park. Walk.
  • 30. http://www.slideshare.net/IgorShkulipa 30 Анонимные методы Новый класс стратегий: public delegate void StrategyDelegate(); public abstract class IStrategyClient { public abstract void UseStrategy(); public StrategyDelegate Strategy { get; set; } } class StrategyClient1 : IStrategyClient { public StrategyClient1() { } public override void UseStrategy() { Strategy(); } }
  • 31. http://www.slideshare.net/IgorShkulipa 31 Использование анонимных методов class Program { static void Main(string[] args) { IStrategyClient stClient = new StrategyClient1(); IStrategy goWork = new GoToWorkStrategy(); IStrategy goGym = new GoToGymStrategy(); IStrategy goWalk = new GoWalkStrategy(); stClient.Strategy = delegate { Console.WriteLine("Anonymous Method:"); goWork.Use(); Console.WriteLine(); }; stClient.UseStrategy(); stClient.Strategy = delegate { Console.WriteLine("Anonymous Method:"); goGym.Use(); Console.WriteLine(); }; stClient.UseStrategy(); stClient.Strategy = delegate { Console.WriteLine("Anonymous Method:"); goWalk.Use(); Console.WriteLine(); }; stClient.UseStrategy(); Console.ReadKey(); } } Anonymous Method: Wake up. Take shower. Dress. Go out. Go to bus stop. Wait. Arrive. Do work. Anonymous Method: Go out. Go to bus stop. Arrive. Do exercises. Anonymous Method: Go out. Go to park. Walk.
  • 32. http://www.slideshare.net/IgorShkulipa 32 Расширяющие методы Расширяющие методы (методы расширения) позволяют "добавлять" методы в существующие типы без создания нового производного типа, перекомпиляции или иного изменения исходного типа. Расширяющие методы являются особым видом статического метода, но они вызываются, как если бы они были методами экземпляра в расширенном типе. Для клиентского кода, написанного на языках C#, нет видимого различия между вызовом метода расширения и вызовом методов, фактически определенных в типе. public static class MyExtensions { public static int WordCount(this String str) { return str.Split(new char[] { ' ', '.', '?' }, StringSplitOptions.RemoveEmptyEntries).Length; } } Методы расширения определяются как статические методы, но вызываются с помощью синтаксиса обращения к методу экземпляра. Их первый параметр определяет, с каким типом оперирует метод, и перед параметром идет модификатор this. Методы расширения находятся в области действия, только если пространство имен было явно импортировано в исходный код с помощью директивы using.
  • 33. http://www.slideshare.net/IgorShkulipa 33 Пример расширяющих методов public static class ExtensionMethods { public static double Angle(this Complex compl) { if ((compl.Re == 0) && (compl.Im >= 0)) { return Math.PI / 2; } if ((compl.Re == 0) && (compl.Im < 0)) { return 3 * Math.PI / 2; } return Math.Atan(compl.Im / compl.Re); } } class Program { static void Main(string[] args) { Complex c1 = new Complex(1,2); Console.WriteLine(c1); double angle = c1.Angle(); Console.WriteLine(angle); Console.ReadKey(); } }
  • 34. http://www.slideshare.net/IgorShkulipa 34 Шаблон проектирования «Visitor» Паттерн Visitor определяет операцию, выполняемую на каждом элементе из некоторой структуры без изменения классов этих объектов. • Паттерн Visitor определяет операцию, выполняемую на каждом элементе из некоторой структуры. Позволяет, не изменяя классы этих объектов, добавлять в них новые операции. Применение расширяющих методов значительно упрощает реализацию этого паттерна.
  • 35. http://www.slideshare.net/IgorShkulipa 35 Классы «компонентов» public class SomeClass1 { public SomeClass1(int c) { SomeProperty1 = c; } public int SomeProperty1 { get; set; } } public class SomeClass2 { public SomeClass2(int c) { SomeProperty2 = c; } public int SomeProperty2 { get; set; } } public class SomeClass3 { public SomeClass3(int c) { SomeProperty3 = c; } public int SomeProperty3 { get; set; } }
  • 36. http://www.slideshare.net/IgorShkulipa 36 Класс-посетитель public static class Visitor { public static void Visit(this SomeClass1 sc1) { Console.WriteLine(sc1.SomeProperty1); } public static void Visit(this SomeClass2 sc2) { Console.WriteLine(sc2.SomeProperty2); } public static void Visit(this SomeClass3 sc3) { Console.WriteLine(sc3.SomeProperty3); } }
  • 37. http://www.slideshare.net/IgorShkulipa 37 Использование class Program { static void Main(string[] args) { SomeClass1 c1 = new SomeClass1(1); SomeClass2 c2 = new SomeClass2(2); SomeClass3 c3 = new SomeClass3(3); c1.Visit(); c2.Visit(); c3.Visit(); Console.ReadKey(); } } 1 2 3
  • 38. http://www.slideshare.net/IgorShkulipa 38 Лабораторная работа № 6. Делегаты, события Используя класс «Квадратная матрица» из лабораторной работы №3, реализовать тестовое приложение «Матричный калькулятор». Добавить к классу расширяющие методы транспонирования матрицы и нахождения следа матрицы (сумма диагональных элементов). Создать делегат на основе анонимного метода приведения матрицы к диагональному виду. Реализовать меню для управления вычислений на основе делегатов с использованием паттерна проектирования «Цепочка ответственности».