Evenimente și Delegări

Evenimentele sunt membri ai unei clase ce permit clasei sau obiectelor clasei să facă notificări, adică să anunțe celelalte obiecte asupra unor schimbări petrecute la nivelul stării lor.

Clasa furnizoare a unui eveniment publică (pune la dispoziția altor clase) acest lucru printr-o declarare event care asociază evenimentului un delegat, adică o referință către o funcție necunoscută căreia i se precizează doar antetul, funcția urmând a fi implementată la nivelul claselor interesate de evenimentul respectiv. Este modul prin care se realizează comunicarea între obiecte.

Tehnica prin care clasele implementează metode (handler-e) ce răspund la evenimente generate de alte clase poartă numele de tratare a evenimentelor. Sintaxa:

[atribut][modificatorAcces]even tipDelegat nume

unde:

modificatorAcces – este la fel ca în cazul metodelor
tipDelegat – este un tip de date, derivat din clasa sigilată Delegate din spaţiul System.

Definirea unui tipDelegat se realizează astfel:

[atribut][modificatorAcces] delegate tipRezultat nume[listaParametri])

Un delegat se poate defini și în afara clasei generatoare de evenimente și poate servi și altor scopuri în afara tratării evenimentelor.

Dorim să definim o metodă asociată unui vector de numere întregi, metodă ce verifică dacă vectorul este o succesiune crescătoare sau descrescătoare. O implementare ”generică” se poare realiza folosind delegări:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Delegari
{
    public delegate bool pereche_ok(object t1, object t2);
    public class Vector
    {
        public const int nmax = 4;
        public int[] v = new int[nmax];
        public Vector()
        {
            Random rand = new Random();
            for (int i = 0; i < nmax; i++)
                v[i] = rand.Next(05);
        }
        public void scrie()
        {
            for (int i = 0; i < nmax; i++)
                Console.Write("{0}, ", v[i]);
            Console.WriteLine();
        }
        public bool aranj(pereche_ok ok)//ok e o delegare către o
        //funcţie necunoscută
        {
            for (int i = 0; i < nmax - 1; i++)
                if (!ok(v[i], v[i + 1])) return false;
            return true;
        }
    }
    class Program
    {
        public static bool f1(object t1, object t2)
        {
            if ((int)t1 >= (int)t2) return true;
            else return false;
        }
        public static bool f2(object t1, object t2)
        {
            if ((int)t1 <= (int)t2) return true;
            else return false;
        }
        static void Main(string[] args)
        {
            Vector x;
            do
            {
                x = new Vector(); x.scrie();
                if (x.aranj(f1)) Console.WriteLine("Monoton descrescator");
                if (x.aranj(f2)) Console.WriteLine("Monoton crescator");
            } while (Console.ReadKey(true).KeyChar != '\x001B'); //Escape
        }
    }
}
 Revenind la evenimente, descriem pe scurt un exemplu teoretic de declarare și tratare a unui eveniment. În clasa Vector se consideră că interschimbarea valorilor a două componente ale unui vector e un eveniment de interes pentru alte obiecte sau clase ale aplicației. Se definește un tip delegat TD (să zicem) cu niște parametri de interes (de exemplu indicii componentelor interschimbate) și un eveniment care are ca asociat un delegat E (de tip TD). Orice obiect x din clasa Vector are un membru E (inițial null). O clasă C interesată să fie înștiințată când se face vreo interschimbare într-un vector pentru a genera o animație (de exemplu), va implementa o metodă M ce realizează animația și va adaăga pe M (prin intermediul unui delegat) la x.E+=new[tip_delegat](M). Cumulând mai multe astfel de referințe, x.E ajunge un fel de listă de metode (handlere). În clasa Vector, în metoda sort, la interschimbarea valorilor a două componente se invocă delegatul E. Invocarea lui E realizează de fapt activarea tuturor metodelor adăugate la E.

Leave a comment