Язык программирования C#9 и платформа .NET5
{Console.WriteLine("Item: {0}", game);}Console.WriteLine();}Как видите, построение выражения запроса LINQ с применением методов класса
напрямую приводит к намного более многословному запросу, чем в случае использования операций запросов С#. Кроме того, поскольку методыEnumerableтребуют передачи делегатов в качестве параметров, обычно необходимо писать лямбда-выражения, чтобы обеспечить обработку входных данных внутренней целью делегата.EnumerableПостроение выражений запросов с использованием типа Enumerable и анонимных методов
Учитывая, что лямбда-выражения C# — это просто сокращенный способ работы с анонимными методами, рассмотрим третье выражение запроса внутри вспомогательного метода
:QueryStringsWithAnonymousMethods()static void QueryStringsWithAnonymousMethods(){Console.WriteLine("***** Using Anonymous Methods *****");string[] currentVideoGames = {"Morrowind", "Uncharted 2","Fallout 3", "Daxter", "SystemShock 2"};// Построить необходимые делегаты Func<>// с использованием анонимных методов.Func<string, bool> searchFilter =delegate(string game) { return game.Contains(" "); };Func<string, string> itemToProcess = delegate(string s) { return s; };// Передать делегаты в методы класса Enumerable.var subset =currentVideoGames.Where(searchFilter).OrderBy(itemToProcess).Select(itemToProcess);// Вывести результаты.foreach (var game in subset){Console.WriteLine("Item: {0}", game);}Console.WriteLine();}Такой вариант выражения запроса оказывается еще более многословным из-за создания вручную делегатов
, применяемых методамиFunc<>,Where()иOrderBy()классаSelect(). Положительная сторона данного подхода связана с тем, что синтаксис анонимных методов позволяет заключить всю обработку, выполняемую делегатами, в единственное определение метода. Тем не менее, этот метод функционально эквивалентен методамEnumerableиQueryStringsWithEnumerableAndLambdas(), созданным в предшествующих разделах.QueryStringsWithOperators()Построение выражений запросов с использованием типа Enumerable и низкоуровневых делегатов
Наконец, если вы хотите строить выражение запроса с применением многословного подхода, то можете отказаться от использования синтаксиса лямбда-выражений и анонимных методов и напрямую создавать цели делегатов для каждого типа
. Ниже показана финальная версия выражения запроса, смоделированная внутри нового типа класса по имениFunc<>:VeryComplexQueryExpressionclass VeryComplexQueryExpression{public static void QueryStringsWithRawDelegates(){Console.WriteLine("***** Using Raw Delegates *****");string[] currentVideoGames = {"Morrowind", "Uncharted 2","Fallout 3", "Daxter", "SystemShock 2"};// Построить необходимые делегаты Func<>.Func<string, bool> searchFilter =new Func<string, bool>(Filter);Func<string, string> itemToProcess =new Func<string,string>(ProcessItem);// Передать делегаты в методы класса Enumerable.var subset =currentVideoGames.Where(searchFilter).OrderBy(itemToProcess).Select(itemToProcess);// Вывести результаты.foreach (var game in subset){Console.WriteLine("Item: {0}", game);}Console.WriteLine();}// Цели делегатов.public static bool Filter(string game){return game.Contains(" ");}public static string ProcessItem(string game){return game;}}Чтобы протестировать такую версию логики обработки строк, метод
понадобится вызвать внутри операторов верхнего уровня в классеQueryStringsWithRawDelegates():Program