Delegaty generyczne
Delegaty generyczne to specjalny rodzaj delegatów, które pozwalają na przechowywanie referencji do metod generycznych. Delegat generyczny jest określony przez typ generyczny i ma takie same ograniczenia na typach generycznych jak metoda, do której jest przypisany.
Aby utworzyć delegata generycznego, należy zdefiniować nowy typ delegata za pomocą słowa
kluczowego delegate
, a następnie określić typ generyczny po nazwie delegata, używając
znaku <>.
delegate T MojDelegat<T>(T arg);
W powyższym przykładzie MyDelegate jest delegatem generycznym, który przyjmuje jeden argument typu T i zwraca typ T.
Delegaty generyczne mogą być używane do przechowywania referencji do metod generycznych, a następnie wywoływania ich przez delegata.
using System;
class MojaKlasa
{
public static T ZrobCos<T>(T arg)
{
// ...
return arg;
}
}
delegate T MojDelagat<T>(T arg);
class Program
{
static void Main()
{
MojDelagat<int> del = MojaKlasa.ZrobCos;
int wynik = del(5);
Console.WriteLine(wynik); // wyświetla 5
}
}
przykład, w którym używamy delegatów generycznych do implementacji systemu porównywania elementów w kolekcji:
using System;
class Kolekcja<T>
{
private T[] elementy;
public Kolekcja(T[] elementy)
{
this.elementy = elementy;
}
public void Sortuj(PorownajDelegat<T> porownaj)
{
Array.Sort(elementy, (x, y) => porownaj(x, y));
}
}
delegate int PorownajDelegat<T>(T x, T y);
class Program
{
static void Main()
{
int[] liczby = { 3, 7, 4, 2, 8, 6 };
var kolekcja = new Kolekcja<int>(liczby);
kolekcja.Sortuj(PorownajLiczby);
foreach (int liczba in liczby)
{
Console.Write(liczba + " ");
}
// wyświetla: 2 3 4 6 7 8
string[] slowa = { "abc", "def", "ghi", "jkl" };
var kolekcja2 = new Kolekcja<string>(slowa);
kolekcja2.Sortuj(PorownajSlowa);
foreach (string slowo in slowa)
{
Console.Write(slowo + " ");
}
// wyświetla: abc def ghi jkl
}
static int PorownajLiczby(int x, int y)
{
return x - y;
}
static int PorownajSlowa(string x, string y)
{
return string.Compare(x, y);
}
}
abc def ghi jkl
W tym przykładzie, delegaty PorownajLiczby
i
PorownajSlowa
zwracają wartość int, która jest
używana przez metodę Array.Sort do określenia kolejności elementów w tablicy.
Dzięki temu, że klasa Kolekcja posiada metodę Sortuj z delegatem generycznym, możemy łatwo posortować różne kolekcje różnych typów danych za pomocą różnych kryteriów porównywania, bez konieczności tworzenia nowych metod sortujących dla każdego z nich.