Delegat (CLI)

Delegaty w języku C# wywodzą się ze wskaźników do funkcji używanych w językach C/C++. Jednak niedoskonałością wskaźników jest to, iż nie gwarantują bezpiecznego zwracania typów danych jak i liczby podawanych parametrów (oraz ich typów). .NET Framework stworzył dla programistów bardzo podobny mechanizm, który zyskał dodatkową funkcjonalność. W efekcie delegaty dbają o bezpieczeństwo typów zwracanych obiektów i metod, na które wskazują. Te nowe typy danych zawierają trzy ważne informacje:

  • adres metody, na którą wskazują
  • parametry tej metody
  • oraz zwracany typ danej metody

Deklaracja

Deklaracje delegatów tworzymy podobnie jak zwykłe funkcje, poprzedzając je jedynie słowem kluczowym delegate

// Delegat potrafiący wskazać na jakąkolwiek metodę posiadającą 2 parametry typu całkowitego i zwracającą typ int
delegate int DelegatBin(int x, int y);

Delegaty mogą wskazywać tylko na funkcje o identycznych typach parametrów i typie zwracanym. Jeżeli chcemy wskazywać na metody np. typu char musimy stworzyć nowego delegata. Delegaty w języku C# są typami danych, które mogą zostać od razu zainicjowane. By tego dokonać musimy stworzyć obiekt delegatu i jako parametr podać nazwę funkcji, na którą ma wskazywać.

int funkcja(int x, int y)
return x + y;
//obiekt delegatu wskazujący na funkcję
DelegatBin nowyDelegat = new DelegatBin(funkcja);
//istnieje również taka możliwość przypisania
nowyDelegat = innaFunkcja;

Prosty przykładowy program pokazujący wykorzystanie

class Program
{
    delegate int DelegacjaM(int x, int y);
    static int Suma(int x, int y)
    {
        return x + y;
    }
    static int Roznica(int x, int y)
    {
       return x - y;
    }
    static void Main(string[] args)
    {
        DelegacjaM delegat = new DelegacjaM(Suma);
        Console.WriteLine("Dodawanie 50+50 " + delegat(50,50) );// zauważmy w tym miejscu że obiekt delegatu zostaje wywołany jak zwykła funkcja

        delegat = Roznica;
        Console.WriteLine("\nOdejmowanie 30-20 " + delegat(30,20) );

        Console.ReadLine();
    }
}

Delegaty można wykorzystać do pisania metod-wtyczek. Zmienna delegatu może otrzymać wartość w czasie wykonywania programu. Temat ten jest kluczem dla odpowiedniego zrozumienia funkcjonowania zdarzeń.

Funkcje zwrotne

Jako że delegaty są obiektami, nie ma problemu przy przesyłaniu ich jako parametrów innych funkcji.

public int FooBar(int x, int y, DelegatBin nowyDelegat)
{
    return x + y + nowyDelegat(50, 60);
}

Wówczas możemy wywołać funkcję, na którą wskazuje obiekt naszego delegatu w funkcji FooBar.

Delegaty złożone

Do delegatu można przypisać więcej niż jedną funkcję, lecz wtedy podczas jego wywołania wywołane zostaną wszystkie te funkcje, które do niego przypisaliśmy. Do przypisywania bądź usuwania funkcji służą operatory += i -=.

Funkcje anonimowe

Istnieje równie możliwość tworzenia funkcji anonimowych przy użyciu delegatów, co pozwala na przyśpieszenie projektowania poprzez pominięcie nazwy metody.

Foo MyFoo = delegate(string M)
{
    Console.WriteLine(M);
};
MyFoo("Hello World");

Bibliografia

Linki zewnętrzne