Обобщенные делегаты Action и Func в C#

Лекции по предмету «Программирование»
Информация о работе
  • Тема: Обобщенные делегаты Action и Func в C#
  • Количество скачиваний: 21
  • Тип: Лекции
  • Предмет: Программирование
  • Количество страниц: 3
  • Язык работы: Русский язык
  • Дата загрузки: 2015-01-04 00:05:38
  • Размер файла: 20.93 кб
Помогла работа? Поделись ссылкой
Информация о документе

Документ предоставляется как есть, мы не несем ответственности, за правильность представленной в нём информации. Используя информацию для подготовки своей работы необходимо помнить, что текст работы может быть устаревшим, работа может не пройти проверку на заимствования.

Если Вы являетесь автором текста представленного на данной странице и не хотите чтобы он был размешён на нашем сайте напишите об этом перейдя по ссылке: «Правообладателям»

Можно ли скачать документ с работой

Да, скачать документ можно бесплатно, без регистрации перейдя по ссылке:

Обобщенные делегаты Action и Func в C#

При использовании делегатов в приложениях требуется выполнить следующие шаги:
• Объявить тип делегата с сигнатурой соответствующего метода (с учетом типа возврата).
• Объявить экземпляр делегата с передачей имени метода в качестве аргумента конструктора;
• Выполнить групповое обращение к методам экземпляра делегата.
При таком подходе получается несколько оригинальных делегатов, которые не могут применяться в других приложениях. В некоторых случаях необходим просто делегат, принимающий набор аргументов и возвращающий или не возвращающий значение. В этих случаях можно воспользоваться встроенными делегатами Action<> и Func<>.
Обобщенный делегат Action<> можно применять для ссылки на метод, который принимает до 16 аргументов и не возвращает значение. Поскольку Action<> является обобщенным делегатом, требуется также указывать типы каждого параметра.
Теперь вместо объявления специального делегата вручную для передачи информации методу DisplayMessage () можно использовать готовый делегат Action<>, как показано ниже:
(Пример из книги Троелсена стр. 372)
class Program
{
// Это цель для делегата Action<>.
static void DisplayMessage(string msg, ConsoleColor txtColor, int printCount)
{
// Установить цвет текста консоли.
ConsoleColor previous = Console.ForegroundColor;
Console.ForegroundColor = txtColor;
for (int i = 0; i < printCount; i++)
{
Console.WriteLine(msg);
}
// Восстановить цвет.
Console.ForegroundColor = previous;
}
static void Main(string[] args)
{
Console.WriteLine("***** Fun with Action and Func *****");
// Использовать делегат Action() для указания на DisplayMessage.
Action<string, ConsoleColor, int> actionTarget =
new Action<string, ConsoleColor, int>(DisplayMessage);
actionTarget("ActionMessage!", ConsoleColor.Yellow, 5);
Console.ReadLine();
}
}
Если нужно указывать на метод с другим возвращаемым значением (и нет желания заниматься написанием собственного делегата), можно прибегнуть к делегату Func<>.
Обобщенный делегат Func<> может указывать на методы, которые (подобно Action<>) принимают вплоть до 16 параметров и имеют специальное возвращаемое значение.
В целях иллюстрации добавим следующий новый метод в класс Program:
// Цель для делегата Func<>.
static int Add(int x, int у)
{
return x + у;
}
Вывод будет иметь вид:

Синий цвет вместо желтого обусловлен тем, что представлен негатив консольного вывода.
Ранее в этой главе был построен специальный делегат BinaryOp для ссылки на методы сложения и вычитания. Теперь можно упростить задачу, воспользовавшись версией Func<>, которая принимает всего три параметра типа. Учтите, что последний в списке параметр типа Func<> — это всегда возвращаемое значение метода. Чтобы закрепить этот момент, предположим, что в классе Program также определен следующий метод:
static string SumToString(int x, int y)
{
return (x + y).ToString();
}
Теперь метод Main () может вызывать каждый из этих методов, как показано ниже:
class Program
{
// Цель для делегата Func<>.
static int Add(int x, int у)
{
return x + у;
}
static string SumToString(int x, int y)
{
return (x + y).ToString();
}
static void Main(string[] args)
{
Func<int, int, int> funcTarget = new Func<int, int, int>(Add);
int result = funcTarget.Invoke(40, 40);
Console.WriteLine("40 + 40 = {0}", result);
Func<int, int, string> funcTarget2 = new Func<int, int, string>(SumToString);
string sum = funcTarget2(90, 300);
Console.WriteLine(sum);
Console.ReadLine();
}
}
Делегаты Action<> и Func<> позволяют исключить объявление специального делегата, но следует ли их применять всегда. Это зависит от ситуации. Во многих случаях делегаты Action<> и Func<> будут предпочтительными. Если имя делегата лучше отражает предметную область, то предпочтительно объявление специального делегата.
Вставка (более четко о вызове Func Action)
Пусть Func имеет прототип
public static Т FirstOrDefault<T>(
this IEnumerable<T> source,
Func<T, bool> predicate);
Тогда запись означает
p => p.dAw.StartsWith("М")
Первое p (перед =>) соответствует this IEnumerable<T> source,
и p.dAw.StartsWith("М") является предикатом
Соответственно прототипу
public static IEnumerable<S> Select<T, S>(
this IEnumerable<T> source,
Func<T, S> selector);
соответствует запись:
lst. Select(p => p)