Что такое делегат Func в C#?

Ответ

Func — это предопределённый обобщённый делегат в пространстве имён System, который инкапсулирует метод, возвращающий значение. Он может принимать от 0 до 16 входных параметров, причём последний параметр типа всегда задаёт возвращаемый тип (TResult).

Основное назначение:

  • Передача методов как параметров (callback-и).
  • Использование в LINQ-запросах и методах высшего порядка.
  • Упрощение кода, работающего с лямбда-выражениями и анонимными методами.

Примеры использования:

// Func без параметров, возвращающий строку
Func<string> getGreeting = () => "Hello, World!";

// Func с двумя параметрами (int, int) и возвращаемым типом int
Func<int, int, int> multiply = (x, y) => x * y;
int result = multiply(5, 4); // result = 20

// Использование в LINQ (Where принимает Func<T, bool>)
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
var evenNumbers = numbers.Where(n => n % 2 == 0); // n => n % 2 == 0 — это Func<int, bool>

Ключевое отличие от Action: Action представляет метод, который не возвращает значение (void), в то время как Func всегда возвращает результат указанного типа.

Ответ 18+ 🔞

А, ну ты глянь, опять эти делегаты пошли, Func там всякий. Ну ладно, раз уж спросил, сейчас разжуём, только не ори, что сложно.

Представь себе, что Func — это такой универсальный шаблон для создания ярлычка на любой метод, который что-то возвращает. Не просто делает и молчит, а именно выдаёт результат. Вот как будто ты даёшь соседу записку: «Сходи в магазин, купи вот это и принеси мне чек». Func — это и есть эта записка, только для кода.

Главная фишка: последний тип в угловых скобках — это всегда то, что метод возвращает. А всё, что перед ним — это то, что он принимает. Может принимать от нуля до шестнадцати параметров, представь себе, овердохуища какая гибкость!

Зачем это надо, спросишь? Ну, например:

  • Чтобы метод в метод запихнуть, как аргумент. Типа «выполни вот это, а результат отдай вон той функции».
  • В LINQ он повсюду. Все эти Where, Select — они жрут на завтрак именно Func и просят добавки.
  • Лямбды с ним просто песня. Вместо того чтобы объявлять отдельный метод на три страницы, написал строчку — и всё, красота.

Смотри, как это выглядит вживую:

// Func без параметров. Просто метод, который возвращает строку. Как кнопка "Сгенерировать оправдание".
Func<string> excuseGenerator = () => "У меня бабушка умерла... в пятый раз.";
string myExcuse = excuseGenerator(); // вот и готово оправдание

// Func с двумя циферками на входе и одной на выходе. Калькулятор, блядь.
Func<int, int, int> power = (number, exp) => (int)Math.Pow(number, exp);
int megaNumber = power(10, 3); // получаем 1000, ёпта!

// А это святое — LINQ. Где — это по сути Func, который спрашивает: "Эй, элемент, ты подходишь под условие?"
List<int> scores = new List<int> { 42, 100, 17, 96, 3 };
var passingScores = scores.Where(s => s > 50); // s => s > 50 — это и есть Func<int, bool>

И главное, не путай с его братаном Action! Всё просто:

  • Func — всегда возвращает значение. Как работяга, который приносит тебе добычу.
  • Action — всегда НЕ возвращает нихуя (void). Как тот самый работяга, который сделал дело, плюнул и пошёл дальше. Результата от него не дождёшься.

Вот и вся магия. Ничего страшного, просто способ говорить компу: «Сделай вот это и скажи, что получилось».