Action
та Func
— це ключові делегати в C#, які спрощують функціональне програмування, забезпечуючи готові шаблони для роботи з методами. Вони усувають потребу в створенні власних делегатів, роблячи код чистішим, багаторазово використовуваним та зрозумілим.
Що таке Action
та Func
?
Делегати в C#: короткий огляд
Делегат — це типізоване посилання на метод, що дозволяє передавати методи як параметри, зберігати їх у змінних або повертати з функцій. Традиційно для цього потрібні власні визначення делегатів, але Action
і Func
значно спрощують цей процес завдяки готовим шаблонам.
Основні відмінності між Action
та Func
Action
: представляє метод із нульовою або більшою кількістю вхідних параметрів без поверненого значення (void
).Func
: представляє метод із нульовою або більшою кількістю вхідних параметрів і поверненим значенням. Останній генеричний параметр вказує тип поверненого значення.
Чому варто використовувати Action
і Func
?
Переваги у сучасному програмуванні на C#:
- Багаторазове використання коду: дозволяє передавати методи як параметри.
- Спрощене оброблення подій: полегшує реалізацію зворотних викликів та логіки, орієнтованої на події.
- Підтримка LINQ: забезпечує функціональні операції, як-от фільтрація (
Where
) та трансформація (Select
). - Динамічні конвеєри: дає змогу комбінувати методи під час виконання.
Практичні приклади
// Використання Action
Action greet = name => Console.WriteLine($"Привіт, {name}!");
greet("Аліса"); // Вивід: Привіт, Аліса!
// Використання Func
Func add = (a, b) => a + b;
int sum = add(5, 10); // Повертає 15
Console.WriteLine(sum); // Вивід: 15
// Використання Action без повернення значення
Action log = message => Console.WriteLine($"Лог: {message}");
log("Операція завершена."); // Вивід: Лог: Операція завершена.
// Використання Func для перетворення даних
Func numberToString = number => $"Число: {number}";
string result = numberToString(42); // Повертає "Число: 42"
Console.WriteLine(result);
// Ланцюжок кількох делегатів Action
Action print = Console.WriteLine;
Action exclaim = s => Console.WriteLine($"{s}!");
Action combined = print + exclaim;
combined("Привіт"); // Вивід: Привіт Привіт!
// Покращення LINQ-запитів за допомогою Func
var numbers = new List { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(n => n % 2 == 0).ToList();
evenNumbers.ForEach(n => Console.WriteLine(n)); // Вивід: 2 4
Поширені помилки та найкращі практики
- Уникайте великих лямбда-функцій, які погіршують читабельність.
// Неправильно
Action print = x => {
if (x % 2 == 0) Console.WriteLine($"{x} парне");
else Console.WriteLine($"{x} непарне");
};
// Використовуйте іменовані методи
void PrintEvenOdd(int x) {
Console.WriteLine(x % 2 == 0 ? $"{x} парне" : $"{x} непарне");
}
Action print = PrintEvenOdd;
print(5); // Вивід: 5 непарне
- Уникайте захоплення змінних у циклах
// Неправильно
List actions = new List();
for (int i = 0; i < 3; i++) {
actions.Add(() => Console.WriteLine(i)); // Виведе: 3, 3, 3
}
actions.ForEach(action => action());
// Правильно
for (int i = 0; i < 3; i++) {
int localI = i;
actions.Add(() => Console.WriteLine(localI)); // Виведе: 0, 1, 2
}
actions.ForEach(action => action());
Висновок
Action
та Func
дають змогу використовувати функціональні принципи програмування в C#, покращуючи читабельність, багаторазовість і модульність коду. Незалежно від того, чи працюєте ви з подієорієнтованим кодом, запитами LINQ чи динамічними конвеєрами, ці делегати спрощують роботу з методами та зменшують обсяг шаблонного коду. Опанувавши їх можливості та уникаючи поширених помилок, ви зможете писати чистіший та ефективніший код на C#.
Перекладено з: Functional Programming in C#: Action and Func