Tematem niniejszego artykułu są delegaty i zdarzenia. Są to
dwa ściśle ze sobą powiązane pojęcia, o których warto parę słów napisać.
Najłatwiej wprowadzić się w świat delegatów wyobrażając
sobie prezydenta Polski, który z braku czasu nie może osobiście uczestniczyć w
uroczystościach prezydenta Stanów Zjednoczonych, pomimo faktu, że został on na
nie zaproszony. Wówczas prezydent Polski wysyła do swojego kolegi zza oceanu
kogoś upoważnionego (np. premiera). Nadaje mu pewne prawa (premier ma obowiązek
reprezentować Polskę), nakazuje mu przekazać ciepłe słowa w postaci
podziękowania za zaproszenie i…przeproszenia za brak udziału J (będą to parametry delegata) oraz
oczekuje, że prezydent Stanów Zjednoczonych będzie jednak zadowolony z
obecności „tylko” premiera znad Wisły.
W takiej sytuacji – premier Polski jest delegatem.
Bardzo często spotkamy się w naszych programach z sytuacją,
w której nasz program wykonuje jakieś działanie, ale nie wie jakich obiektów a
nawet metod ma w tym celu użyć. Na przykład: naciśnięcie przycisku ma
poinformować inny obiekt, że przycisk został przyciśnięty. Ale jaki to obiekt?
Nie wiadomo, dlatego najlepszym rozwiązaniem jest połączenie tego przycisku z
delegatem, który następnie w czasie wykonywania się programu wywoła odpowiednią
metodę.
Wiemy już mniej więcej do czego służą delegaty, ale tematem
dzisiejszego artykułu są również zdarzenia. Nie jest to przypadkowe, bowiem są
one często właśnie razem z delegatami spotykane w programach. Możemy powiedzieć
więcej, delegaty i zdarzenia są ściśle powiązane ze sobą, ponieważ delegat
potrafi obsługiwać zdarzenie.
A co to jest zdarzenie? Zdarzenie to pojęcie określające, że
„coś się wydarzyło” w naszym programie, np. kliknięcie przycisku jest chyba
najprostszym zdarzeniem jakie możemy osiągnąć w naszej aplikacji.
Delegaty to obiekty, w pełni obsługiwane przez język C# 2.0.
Z punktu widzenia programisty delegat to typ referencyjny, który stanowi
interfejs metody o odpowiedniej sygnaturze oraz zwracanym typie. Poniżej
prezentujemy sposób deklarowania delegatów:
public delegate
string MojDelegat(object mojObjekt1, object
MojObject2);
A więc delegat tworzymy używając słowa kluczowego delegate,
po którym znajduje się sygnatura metod, których interfejsem może być dany
delegat.
W powyższym fragmencie kodu utworzyliśmy więc delegat o
nazwie MojDelegat, który może zawierać dowolną metodę przyjmującą jako
parametry 2 obiekty i zwracającą ciąg łańcuchów (string).
Do zapamiętania: delegat używamy do wywołania metody, którą
on zawiera. Nieistotne jest, czy w danej chwili delegat zawiera metodę
składową (tworzymy następnie egzemplarz tej metody, która zwraca odpowiedni typ
i ma odpowiednią sygnaturę), czy używa metod anonimowych (o nich w niniejszym
artykule też napiszemy parę słów) - istotne bowiem, że delegat metody te
potrafi wywołać.
Napiszmy więc pierwszy przykład, który będzie prezentować
sposób używania delegatów:
public class Delegaty
{
public
delegate int MojDelegat(int a, int b);
public
int Dodaj(int
a, int b)
{
return a + b;
}
public
int Odejmij(int
a, int b)
{
return a - b;
}
public
int Pomnoz(int
a, int b)
{
return a * b;
}
public
int Podziel(int
a, int b)
{
return a / b;
}
}
class Glowna
{
static
void Main()
{
Delegaty d = new Delegaty();
Delegaty.MojDelegat dodawanie = new
Delegaty.MojDelegat(d.Dodaj);
int
wynikDodawania = dodawanie(4, 6);
System.Console.WriteLine("Wynik dodawania wynosi: {0}.",
wynikDodawania.ToString());
Delegaty.MojDelegat odejmowanie = new
Delegaty.MojDelegat(d.Odejmij);
int
wynikOdejmowania = odejmowanie(22, 11);
System.Console.WriteLine("Wynik
odejmowania wynosi: {0}.",
wynikOdejmowania.ToString());
Delegaty.MojDelegat mnozenie = new
Delegaty.MojDelegat(d.Pomnoz);
int
wynikMnozenia = mnozenie(3, 8);
System.Console.WriteLine("Wynik mnożenia wynosi: {0}.",
wynikMnozenia.ToString());
Delegaty.MojDelegat dzielenie = new
Delegaty.MojDelegat(d.Podziel);
int
wynikDzielenia = dzielenie(64, 8);
System.Console.WriteLine("Wynik dzielenia wynosi: {0}.", wynikDzielenia.ToString());
}
}
W powyższym przykładzie
zdefiniowaliśmy delegat o nazwie MojDelegat, który może zawierać dowolną
metodę, która musi spełnić 2 warunki (de facto określone właśnie przez
definicję delegata):