Press "Enter" to skip to content

eventy w C# nie są takie straszne.

Wyobraźmy sobie sytuację, w której chcemy, aby dana właściwość informowała nas o tym, że ustawiła zmiennej pewną wartość. Chcemy, aby wywołała zdarzenie z grupy zdarzeń, zależnie od tego, jaką wartość osiągnie nasza zmienna. Oczywiście możemy sobie zareagować na nasze zdarzenie jak chcemy:) Opisaną sytuację możemy zaimplementować w następujący sposób:

 
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace testZdarzeń
{
    delegate void Mod2Handler();
    delegate void Mod4Handler();
    delegate void Mod10Handler();
    class numerek{

        public event Mod4Handler Mod4event;
        public event Mod2Handler Mod2event;
        public event Mod10Handler Mod10event;
        private int _wartosc = -1;
        public int wartosc{
            get {
                return _wartosc;
            }
            set{
                if (value != 0)
                {
                    _wartosc = value;
                    if (value % 2 == 0) if (Mod2event != null) Mod2event();
                    if (value % 4 == 0) if (Mod4event != null) Mod4event();
                    if (value % 10 == 0) if (Mod10event != null) Mod10event();

                }
                else Console.WriteLine("gdzie mi z tym zerem");
            }
        }
    }
    class Program
    {
        static void dwojka() { Console.WriteLine("Liczba podzielna przez 2"); }
        static void czworka() { Console.WriteLine("Liczba podzielna przez 4"); }
        static void dycha() { Console.WriteLine("Liczba podzielna przez 10"); }
        static void dziesiatka() { Console.WriteLine("Ta liczba ma zero na końcu:)"); }
        static void Main(string[] args)
        {
            numerek a = new numerek();
            a.Mod2event +=new Mod2Handler(dwojka);
            a.Mod4event += new Mod4Handler(czworka);
            a.Mod10event +=new Mod10Handler(dycha);
            a.Mod10event += new Mod10Handler(dziesiatka);
            for (int i = 0; i<100; i++){
                a.wartosc = i;
                Console.WriteLine(a.wartosc);
                if (i % 5 == 0) Console.ReadKey();
            }
        }

    }

W klasie numerek mamy do dyspozycji publiczne eventy, które są wywoływane w setterze właściwości wartosc. Zależnie od wartości (a raczej od tego czy spełnia jeden z warunków), wywoływana jest grupa funkcji przyporządkowana do danego zdarzenia. Zachowana zostaje kolejność sprawdzanych warunków. Zachowana zostaje także kolejność poszczególnych funkcji dodanych do danego zdarzenia. Warto również zauważyć, że eventy są wywoływane w momencie przypisania wartości, czyli przed jej wypisaniem (a więc tam, gdzie w kodzie rzeczywiście występują). Co zyskujemy w porównaniu z implementacją interfejsu INotifyPropertyChanged? Przede wszystkim możliwość wywołania kilku zdarzeń dla zmiany jednej wartości (a nie tylko jeden- PropertyChanged). Nie należy mylić tego z wywołaniem kilku funkcji do obsługi jednego zdarzenia (bo to jest możliwe przy jednym evencie - jak mamy dla %10).

Oczywiście dla uproszczenia podano tu działanie na intach - równie dobrze mogłoby to być przypisanie jednej z wartości enum, i zależnie od niej wywołanie szeregu funkcji.