понедельник, 3 января 2022 г.

Action, Predicate и Func (универсальные делегаты) в C#

 Action, Predicate и Func

В C# есть готовые универсальные делегаты ActionPredicate и Func.
Action
namespace System
{
     public delegate void Action();
     public delegate void Action<in T>(T obj);
     public delegate void Action<in T1, in T2>(T1 arg1, T2 arg2);
     ...
     public delegate void Action<in T1, in T2, ... in T15>(T1 arg1, T2 arg2, ... T15 arg15);
}
Predicate
namespace System
{
     public delegate bool Predicate<in T>(T obj);
}
Func
namespace System
{
     public delegate TResult Func<out TResult>();
     public delegate TResult Func<in T, out TResult>(T arg);
     public delegate TResult Func<in T1, in T2, out TResult>(T1 arg1, T2 arg2);
     ...
     public delegate TResult Func<in T1, in T2, ..., in T15, out TResult>(T1 arg1, T2 arg2, ..., T15 arg15);
}
Эти делегаты используются в разных ситуациях.
using System;

// подключаем библиотеку для работы с файлами
using System.IO;

namespace ConsoleApplication1
{
     public class Device
     {
          public void ShowTextOnDisplay(String text)
          {
               // выводим текст на экран
               Console.WriteLine(text);
          }

          public void StoreTextInFile(String text)
          {
               // сохраняем текст в файл
               string filePath = @"D:\1.txt";
               File.WriteAllText(filePath, text);
          }
     }

     class Program
     {
          static void CalculateSum(int[] values, Action<string> showMethod)
          {
               // считаем сумму
               int result = 0;
               for (int i=0; i<values.Length; i++)
                    result += values[i];

               // выводим результат
               showMethod(result.ToString());
          }

          static void Main(string[] args)
          {
               Device device = new Device();

               // массив чисел и функция ShowTextOnDisplay это делегат Action<string>
               CalculateSum(new int[] { 10, 5, 7 }, device.ShowTextOnDisplay);

               // массив чисел и функция StoreTextInFile это делегат Action<string>
               CalculateSum(new int[] { 6, 23, 72, 45, 67 }, device.StoreTextInFile);
          }
     }
}
Predicate
Делегат Predicate принимает 1 параметр T obj и возвращает значение bool
Делегат Predicate используется для сравнения объекта T определенному условию
  C#  
using System;

// подключаем библиотеку для работы с файлами
using System.IO;

namespace ConsoleApplication1
{
     class Program
     {
          static void CalculateSum(int[] values, Predicate<int> filterPredicate)
          {
               // считаем сумму
               int result = 0;
               for (int i = 0; i < values.Length; i++)
               {
                    int value = values[i];

                    // filtering
                    if (filterPredicate(value))
                         result += values[i];
               }

               // выводим результат
               Console.WriteLine(result);
          }

          static void Main(string[] args)
          {
               // Считаем сумму для чисел > 5
               CalculateSum(new int[] { 10, 5, 7, 23 }, delegate(int value) { return value > 5 ? true: false; });

               // Считаем сумму для чисел > 23 и чисел < 50
               CalculateSum(new int[] { 6, 23, 72, 45, 67 }, delegate(int value) { return (value > 23 && value < 50) ? true : false; });
          }
     }
}
Func
Делегат Func принимает от 0 до 16 параметров любого типа и возвращает значение out T
Делегат Func часто используется как параметр в методах.
Внимание! Последний параметр у Func это return тип.
Пример1:
Func<string, string> myFunc = MyUpper;

public static string MyUpper(string value)
{
    return value.ToUpper();
}

Пример2:
Func<int, int, string> myFunc = MySum;

public static string MySum(int value1, int value2)
{
    return (value1 + value2).ToString();
}
  C#  
using System;
using System.Linq;
using System.Collections.Generic;

namespace ConsoleApplication1
{
     class Program
     {
          public static string MySelector(string value)
          {
               return value.ToUpper();
          }

          static void Main(string[] args)
          {
               // массив
               string[] arrNames = new string[] { "Hello""Good morning""Bye" };

               // делегат Func
               Func<stringstringselector = MySelector;

               // преобразуем слова
               IEnumerable<string> convertedNames = Enumerable.Select(arrNames, selector);

               // показываем результат на экране
               foreach (string str in convertedNames)
                    Console.WriteLine(str);

               // на экране увидим
               // "HELLO"
               // "GOOD MORNING"
               // "BYE"
          }
     }
}
Объяснение примера
В C# есть Select в который 2-ым параметром передается делегат Func

Комментариев нет:

Отправить комментарий

Паттерн 'Репозиторий' в ASP.NET

  Последнее обновление: 1.11.2015         Одним из наиболее часто используемых паттернов при работе с данными является паттерн 'Репозито...