451
Обобщенные.делегаты
Обобщенные делегаты
Много
лет назад, когда среда .NET Framework только начинала разрабатываться,
в Microsoft ввели понятие делегатов. По мере добавления в FCL классов появлялись
и новые типы делегатов. Со временем их накопилось изрядное количество. Только
в библиотеке
MSCorLib dll
их около 50. Вот некоторые из них:
public delegate void TryCode(Object userData);
public delegate void WaitCallback(Object state);
public delegate void TimerCallback(Object state);
public delegate void ContextCallback(Object state);
public delegate void SendOrPostCallback(Object state);
public delegate void ParameterizedThreadStart(Object obj);
Вы не заметили определенное сходство в отобранных мной делегатах? На
самом
деле они одинаковы: переменная любого из этих делегатов должна ссылаться на
метод, получающий
Object
и возвращающий
void
. Соответственно весь этот набор
делегатов не нужен — вполне можно обойтись одним.
Так как современная версия .NET Framework
поддерживает обобщения, нам на
самом деле нужно всего лишь несколько обобщенных делегатов (определенных
в пространстве имен
System
), представляющих методы, которые могут принимать
до 16 аргументов:
public delegate void Action(); // Этот делегат не обобщенный
public delegate void Action
(T obj);
public delegate void Action(T1 arg1, T2 arg2);
public delegate void Action(T1 arg1, T2 arg2, T3 arg3);
...
public delegate void Action(T1 arg1, ..., T16 arg16);
В .NET Framework имеются 17 делегатов
Action
, от не имеющих аргументов
вообще до имеющих 16 аргументов. Чтобы вызвать метод с большим количеством
аргументов, придется определить собственного делегата, но это уже маловероятно.
Кроме делегатов
Action
в .NET Framework имеется 17 делегатов
Func
, которые
позволяют методу обратного вызова вернуть значение:
public delegate TResult Func();
public delegate TResult Func(T arg);
public delegate TResult Func(T1 arg1, T2 arg2);
public delegate TResult Func(T1 arg1, T2 arg2, T3 arg3);
...
public delegate TResult Func(T1 arg1, ..., T16 arg16);
Вместо определения собственных типов делегатов рекомендуется по мере воз-
можности использовать обобщенных делегатов; ведь это уменьшает количество
типов в системе и упрощает код. Однако, если нужно передать аргумент по ссылке,
используя ключевые слова
ref
или
out
, может потребоваться определение соб-
ственного делегата:
delegate void Bar(ref Int32 z);
452
Глава.17 .Делегаты
Аналогично нужно действовать в ситуациях, когда требуется передать делегату
переменное число параметров при помощи ключевого слова
params
,
если вы хоти-
те задать значения по умолчанию для аргументов делегата или если потребуется
установить ограничение для аргумента-типа.
При работе с делегатами, использующими обобщенные аргументы и возвращаю-
щими значения, не следует забывать про ковариантность и контравариантность, так
как это расширяет область применения делегатов.
Дополнительная информация
по этой теме приведена в главе 12.
Do'stlaringiz bilan baham: