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
- Adam Boduch "Wstęp do programowania w języku C#" Wydawnictwo Helion
- Christian Nagel, Bill Evjen, Jay Glynn, Karli Watson, Morgan Skinner "Professional C# 4 and .NET" Wrox
- Marcin Gościniak "Delegaty w C#"