← Все вопросы

Чем отличаются Action, Func и Predicate? Когда какой использовать?

Задан 9 месяцев назад531 просмотров2 ответа
8

Начал писать на C# и постоянно вижу в чужом коде Action, Func<> и Predicate<> вместо объявления своих делегатов через delegate. Понял, что это какие-то встроенные делегаты, но не врубаюсь, в чём между ними разница и когда что брать.

Вот, например, такой кусок — почему тут Func, а не Action?

List<int> nums = new() { 1, 2, 3, 4, 5 };
Func<int, bool> isEven = x => x % 2 == 0;
var evens = nums.Where(isEven);

А в другом месте видел Action<string>. Можно по-человечески объяснить, чем они отличаются и почему вообще три разных типа?

2 ответа

14
✓ Принятый ответ — помог автору

Это три готовых обобщённых делегата, чтобы не объявлять свои каждый раз. Разница только в том, что они возвращают:

  • Action — метод, который ничего не возвращает (void). Action<int, string> — принимает int и string, возвращает void.
  • Func — метод, который что-то возвращает. Последний параметр типа — это тип возврата. Func<int, bool> — принимает int, возвращает bool.
  • Predicate<T> — частный случай: принимает T, возвращает bool. По сути то же, что Func<T, bool>, просто читается как «условие/проверка».
Action<string> log = msg => Console.WriteLine(msg);        // void
Func<int, int, int> sum = (a, b) => a + b;                 // возвращает int
Predicate<int> isPositive = x => x > 0;                    // возвращает bool

log("привет");
Console.WriteLine(sum(2, 3));        // 5
Console.WriteLine(isPositive(-4));   // False

Правило простое: возвращаешь значение → Func, не возвращаешь → Action, проверка на условие → Predicate (или Func<T,bool>). В LINQ почти везде Func, поэтому ты его и видишь.

5

Маленькое практическое уточнение: Predicate<T> в современных API почти не используют — методы LINQ (Where, Any, Count) принимают Func<T, bool>. Predicate<T> остался в основном в старых методах List<T>, например Find и RemoveAll:

var list = new List<int> { 1, 2, 3, 4 };
list.RemoveAll(x => x % 2 == 0); // тут параметр — Predicate<int>

Так что на практике чаще всего хватает Action и Func, а Predicate встречается реже.

Ваш ответ

Войдите, чтобы ответить на вопрос.
Поддержать проект