Obsługa zdarzeń prezentuje fajowe zjawisko dosłownego "odpowiadania" kodu na sygnał wysłany przez konkretny obiekt. Używając słowa kluczowego "event" w języku C#, możemy zrealizować taką obsługę zdarzeń. Jak poprzednio podzielimy to sobie na teorię i praktykę razem z ukazaniem wszystkich skutków naszych działań.

"EVENT" W JĘZYKU C# REAGUJE NA POTRZEBY OBIEKTÓW!

Przeczytanie ze zrozumieniem treści na temat delegatów jest OBOWIĄZKOWE! Nie zrozumiecie w pełni wątku obsługi zdarzeń bez znajomości słowa kluczowego "delegate" i posługiwania się instancjami.

Zaczynamy. "event" jak możecie się domyślić oznacza z angielskiego "zdarzenie". W kontekście programowania chodzi o zaprogramowanie możliwości "wszczepiania" kodu wykonującego się w momencie wysłania przez obiekt "sygnału". "Sygnał" piszę trochę na wyrost, bo w rzeczywistości jest to wywołanie albo lepiej, uruchomienie tego zdarzenia, a w połączeniu z delegatem będzie to stanowiło "most" łączący ten zapalnik z referencjami do metod jakie mają zostać wykonane.

PRZYKŁAD KODU ŹRÓDŁOWEGO

Jaśniej nie da się tego wytłumaczyć bez sięgnięcia po przykład kodu. Przejdźmy do praktyki. Wyjaśnienia znajdują się poniżej:

KLASA "MYCLASS"
internal delegate void MyClassOnPointsIncreaseDelegate();
	
class MyClass
{
	public event MyClassOnPointsIncreaseDelegate OnPointsIncrease;
	public int Points
	{
		get
		{
			return points;
		}
		set
		{
			points = value;

			if(value > 0 && OnPointsIncrease != null)
			{
				OnPointsIncrease();
			}
		}
	}

	private int points;
}
KLASA "PROGRAM"
class Program
{
	static void Main(string[] args)
	{
		MyClass mc = new MyClass();
		
		mc.OnPointsIncrease += MyClassOnPointsIncrease;
		mc.Points += 100;
		mc.Points -= 200;
		mc.Points += 1000;
	}
	
	static void MyClassOnPointsIncrease(MyClass mc)
	{
		Console.WriteLine("Obecna liczba punktów: {0:D7}", mc.Points);
	}
}

Skupimy się najpierw na "MyClass". Aby utworzyć obsługę zdarzeń od klasy wysyłającej "sygnał", wymagane są dwie rzeczy: zdarzenie w postaci składowej dostępnej publicznie, ale jeszcze wcześniej wstawienie delegata, który będzie to zdarzenie reprezentował. "event" w języku C# zaprezentowany na przykładzie, składa się z kilku rzeczy:

public event MyClassOnPointsIncreaseDelegate OnPointsIncrease;

Po pierwsze, modyfikator dostępu. Zwykle określa się go jako publiczny, bo inaczej cała praca nie ma żadnego sensu (jak będziemy "podpinać" później metody na zewnątrz?). Dalej jest słowo kluczowe "event", a następnie nazwa typu delegata. Na końcu jest konieczność wprowadzenia etykiety dla naszego obiektu zdarzenia.

Wstawiłem przykładową właściwość kontrolującą wyświetlanie i przypisywanie wartości prywatnej danej typu "int". Spójrzcie na blok "settera". Zaraz po instrukcji przypisania, znajduje się instrukcja warunkowa weryfikująca dwie rzeczy: czy do punktów dodaje się wartość dodatnią i coś jeszcze, o wiele istotniejszego. Czy obiekt naszego zdarzenia nie jest pusty! Jak wspomniałem w artykule o samych delegatach, po "odjęciu" wszystkich referencji z delegata, automatycznie się on "nulluje" (podlega usunięciu). To oznacza również że na samym początku programu, wszystkie delegaty jak i obiekty zdarzeń posiadają wartość "null". One przestają być "nullami" od chwili kiedy doda się do nich pierwszą referencję (albo wykorzysta się jawnie konstruktor). Dlatego tuż przed wykonaniem kodu "podpiętego" pod zdarzenie, musi się odbyć weryfikacja wartości "null".

Kiedy program stwierdzi, że obiekt zdarzenia nie jest "nullem", będzie to oznaczać że znajdują się jakieś referencje do metod w związku z powyższym, obsługa zdarzeń może zostać bez przeszkód zrealizowana. Każda funkcja bez wyjątku, która zostanie dodana do obiektu zdarzenia, zostanie wtedy wykonana. Trzymając się fachowej terminologii, taka funkcja ładniej się nazywa jako "procedura obsługi zdarzenia".

A teraz spójrzcie na klasę "Program", w której znajduje się utworzenie instancji poprzedniej klasy. Zaraz po niej wykorzystujemy otwartą furtkę do naszego obiektu "event" w języku C#. Ten zapis chyba już nie budzi wątpliwości, prawda? Postępujemy tak samo jak przy dodawaniu referencji do delegata. Wprowadzamy nazwę metody BEZ NAWIASÓW (bo to nie jest wywołanie), której sygnatura pokrywa się z tą podaną w deklaracji delegata, i od tej pory będzie ona "czuwała" i czekała na znak jaki wyśle jej klasa "MyClass". A stanie się tak w momencie podniesienia wartości "points" przy użyciu właściwości. Czynimy tak więc i w trakcie działania programu spowoduje to poinformowanie wszystkich podpiętych do zdarzenia funkcji i ich bezwzględne wykonanie jedna po drugiej. Zwróćcie uwagę, że potem następuje odejmowanie. Czy wtedy dojdzie do egzekucji? Nie, bo w instrukcji warunkowej jest jasno podane, że to dotyczy tylko składników dodatnich. Za trzecim razem ponownie dodajemy sobie ileś tam punktów i kolejny raz wszystkie metody otrzymają "zapalnik". Na tym to polega.

Słowo kluczowe "event" w języku C#

"event" aktywuje delegata umożliwiając programowanie obsługi zdarzeń i wykonywania poleceń po wysłaniu przez obiekt "sygnału".


Koniec! Moim zdaniem temat bardzo widowiskowy mogący dać dużo możliwości, choć trzeba przyznać że trochę wymagający pod kątem rozumienia teoretycznego. Zapewniam Was, że jeśli opanujecie delegaty ("delegate") i zdarzenia ("event" w języku C#), to kod będzie jeszcze bardziej profesjonalny i jeszcze bardziej zachęcający do traktowania Was na poważnie.

PODOBNE ARTYKUŁY