Комментарии (1)
Ответ сгенерирован нейросетью и может содержать ошибки
Основные делегаты в LINQ
В LINQ (Language Integrated Query) ключевую роль играют делегаты, которые определяют сигнатуры функций для операций с данными. Наиболее важными являются следующие предопределенные делегаты:
1. Func<T, TResult>
Самый распространенный делегат, представляющий метод с возвращаемым значением. Имеет различные варианты с количеством параметров от 0 до 16.
// Примеры Func делегатов
Func<int, bool> isEven = x => x % 2 == 0; // Принимает int, возвращает bool
Func<int, string, string> format = (num, text) => $"{text}: {num}";
Func<double> getRandom = () => new Random().NextDouble(); // Без параметров
2. Action<T>
Делегат для методов, которые не возвращают значения (void). Также поддерживает до 16 параметров.
// Примеры Action делегатов
Action<string> logMessage = message => Console.WriteLine(message);
Action<int, int> printSum = (a, b) => Console.WriteLine(a + b);
3. Predicate<T>
Специализированный делегат для проверки условий. Всегда возвращает bool.
// Пример Predicate делегата
Predicate<string> isValid = s => !string.IsNullOrEmpty(s);
List<string> names = new List<string> { "Alice", "", "Bob" };
var validNames = names.FindAll(isValid); // Находит все непустые строки
4. Comparison<T>
Делегат для сравнения двух объектов одного типа, возвращающий целое число.
// Пример Comparison делегата
Comparison<string> lengthComparer = (x, y) => x.Length.CompareTo(y.Length);
List<string> words = new List<string> { "apple", "kiwi", "banana" };
words.Sort(lengthComparer); // Сортировка по длине строк
Практическое применение в LINQ
Эти делегаты активно используются в стандартных операторах LINQ:
List<int> numbers = new List<int> { 1, 2, 3, 4, 5 };
// Использование Func в Where
var evenNumbers = numbers.Where(x => x % 2 == 0); // x => x % 2 == 0 - это Func<int, bool>
// Использование Func в Select
var squares = numbers.Select(n => n * n); // Func<int, int>
// Использование Func в OrderBy
var sorted = numbers.OrderBy(n => n.ToString()); // Func<int, string>
Эволюция делегатов в C#
С развитием языка появились более удобные способы работы с делегатами:
- Анонимные методы (C# 2.0)
- Лямбда-выражения (C# 3.0) - наиболее распространенный подход
- Локальные функции (C# 7.0)
// Эволюция синтаксиса
Predicate<int> oldWay = delegate(int x) { return x > 0; }; // Анонимный метод
Predicate<int> lambdaWay = x => x > 0; // Лямбда-выражение
bool LocalFunction(int x) => x > 0; // Локальная функция
Ключевые особенности
- Func используется в большинстве операций LINQ (Where, Select, OrderBy, GroupBy и др.)
- Predicate чаще встречается в методах коллекций (
List<T>.FindAll,Array.Find) - Современный C# предпочитает Func<bool> вместо Predicate в новых API
- Делегаты в LINQ позволяют реализовать отложенное выполнение (deferred execution)
- Компилятор C# автоматически преобразует лямбда-выражения в соответствующие делегаты
Эти делегаты образуют фундамент функционального программирования в C# и делают LINQ мощным и выразительным инструментом для работы с данными.