Кратко съдържание



страница48/73
Дата21.07.2018
Размер9.03 Mb.
#76887
1   ...   44   45   46   47   48   49   50   51   ...   73

Събития и интерфейси


Както беше вече споменато, за разлика от делегатите, събитията могат да бъдат членове на интерфейси. Следващият код илюстрира това:

public interface IClickable

{

event ClickEventHandler Click;



}

Имплементиране на събития в интерфейс


При имплементация на интерфейса, имплементиращият клас трябва да предизвиква събитието, което е декларирано в интерфейса. Допустимо е освен това при конкретната имплементация класът да реализира специ­фични add и remove методи, с което да промени тяхното поведение по подразбиране и да добави нетривиална логика.

Когато в интерфейс се декларират свойства, имплементиращият клас е длъжен да реализира техните методи (set, get или и двата, в зависимост от декларацията). За разлика от свойствата, при събитията не е задъл­жително да се имплементират специфични add и remove методи – ако специфична реализация липсва, те получават поведение по подразби­ране, съответно да добавят и премахват обработчици на събитието.


Събития и интерфейси – пример


В настоящия пример ще разгледаме съвместната употреба на събития и интерфейси:

public delegate void ClickEventHandler(object aSender,

EventArgs aEventArgs);


public interface IClickable

{

event ClickEventHandler Click;



}
public class Button : IClickable

{

private ClickEventHandler mClick;



// Implement the event from the interface IClickable

public event ClickEventHandler Click

{

add


{

mClick += value;

Console.WriteLine("Subscribed to Button.Clicked event.");

}

remove



{

mClick -= value;

Console.WriteLine(

"Unsubscribed from Button.Clicked event.");

}

}
protected void OnClick()



{

if (mClick != null)

{

mClick(this, EventArgs.Empty);



}

}
public void FireClick()

{

Console.WriteLine("Button.FireClick() called.");



OnClick();

}

}


public class ButtonTest

{

private static void Button_Click(object aSender,



EventArgs aEventArgs)

{

Console.WriteLine("Button_Click() event called.");



}
public static void Main()

{

Button button = new Button();



button.Click +=

new ClickEventHandler(Button_Click);

button.FireClick();

button.Click -=

new ClickEventHandler(Button_Click);

}

}



След изпълнение на примера се получава следният резултат:


Описание на примера


В началото се декларира делегат, който ще бъде тип на събитието, дефи­нирано в интерфейса. След това се дефинира интерфейс IClickable с единствен член, който е събитието Click. Класът Button имплементира интерфейса IClickable, като добавя частна член-променлива от типа на делегата и реализира специфични add и remove методи за събитието, чрез които се извършва манипулация на списъка с методи на променливата-делегат. Освен това в класа се декларират методи за предизвикване на събитието и извикване на обработчиците му. Класът ButtonTest дефинира метод-обработчик на събитието Click и в главния си метод създава инстанция на класа Button, абонира се за събитието Click, предизвиква го и след това премахва абонамента.

Интерфейси, събития, делегати


В .NET Framework поведението "обратно извикване" може да се реализира чрез три механизма: делегати, събития и интерфейси. Досега разгледахме използването на делегатите и събитията.

"Обратно извикване" чрез интерфейси


Чрез интерфейси "обратно извикване" може да се реализира като мето­дът, който трябва да се използва за "обратно извикване" се декларира като член на интерфейс. След това в различните класове, които импле­ментират интерфейса, методът може да бъде имплементиран по различни начини и така той не се обвързва с конкретна реализация. В класа, който ще извършва обръщение към callback метода се декларира променлива от типа на интерфейса, който съдържа декларацията на съответния метод. На тази променлива могат да се присвояват референции към обекти от различни класове, имплементиращи съответния интерфейс. По този начин могат да бъдат викани методи с различно поведение, в зависимост от необходимостта.

"Обратно извикване" чрез интерфейси – пример


Следващият пример показва как можем да използваме интерфейс, за да реализираме "обратно извикване":

public interface IClickListener

{

void ClickPerformed();



}
public class Button

{

private IClickListener mClickListener;


public Button(IClickListener aClickListener)

{

mClickListener = aClickListener;



}
public void DoClick()

{

if (mClickListener != null)



{

mClickListener.ClickPerformed();

}

}

}


public class ButtonTest : IClickListener

{

public static void Main()



{

ButtonTest buttonTest = new ButtonTest();

Button button = new Button(buttonTest);

button.DoClick();

}
void IClickListener.ClickPerformed()

{

Console.WriteLine("Click performed.");



}

}


След изпълнения на примера се получава следният резултат:


Описание на примера


Интерфейсът IClickListener съдържа метода ClickPerformed(), чрез който ще се реализира "обратно извикване". В класа Button са дефи­нирани член mClickListener от типа на интерфейса и метод DoClick(), който извиква интерфейсния метод ClickPerformed(). Класът ButtonTest имплементира интерфейса IClickListener и в главната си функция създава обект от тип Button и извиква метода му DoClick(). При това се извиква имплементацията на ClickPerformed(), която е предоставена от ButtonTest.

Кога да използваме интерфейси?


Въпреки че "обратно извикване" може да се реализира чрез интерфейси, това не е типично приложение на интерфейс и е добре да се използва по-рядко. Докато делегатите дават възможност за извикване на множество методи, то всички те трябва да имат еднакъв връщан тип и сигнатура. При интерфейсите няма такова ограничение, и затова те трябва да се ползват именно когато е нужно даден обект да предоставя съвкупност от много различни callback методи.

Кога да използваме събития?


Събитията се използват, когато разработваме компоненти, които трябва да известяват своя притежател за нещо, обикновено за промяна в теку­щото състояние или за извършване на някакво действие. Освен това чрез използване на събитията се поддържа съвместимост с компонентния модел на .NET.

Кога да използваме делегати?


Основните приложения на делегатите са за асинхронна обработка посредством callback методи и за даване на възможност на потребителите на клас да предоставят метод, извършващ специфична обработка, която не е предварително фиксирана. В този случай извикването на callback метода не е свързано с настъпването на някаква промяна или събитие, както е при събитията. Делегатите се използват, когато имаме единичен callback метод, който не е свързан с компонентния модел на .NET.



Сподели с приятели:
1   ...   44   45   46   47   48   49   50   51   ...   73




©obuch.info 2024
отнасят до администрацията

    Начална страница