в приведенном примере кода скрыто от глаз, но "за кулисами" работа происходит с типом
OrderedEnumerable
. На объекте указанного типа вызывается обобщенный метод
OrderBy
, который также принимает параметр типа делегата
Func<>
. Теперь производится передача всех элементов по очереди посредством подходящего лямбда-выражения. Результатом вызова
OrderBy
является новая упорядоченная последовательность первоначальных данных.
И, наконец, осуществляется вызов метода
Select
на последовательности, возвращенной
OrderBy
,
который в итоге дает финальный набор данных, сохраняемый в неявно типизированной переменной по имени
subset
.
Конечно, такой "длинный" запрос LINQ несколько сложнее для восприятия, чем предыдущий пример с операциями запросов LINQ. Без сомнения, часть сложности связана с объединением в цепочку вызовов посредством операции точки. Вот тот же самый запрос с выделением каждого шага в отдельный фрагмент (разбивать запрос на части можно разными способами):
static void QueryStringsWithEnumerableAndLambdas2
{
Console.WriteLine("***** Using Enumerable / Lambda Expressions *****");
var orderedGames = gamesWithSpaces.OrderBy(game => game);
var subset = orderedGames.Select(game => game);
foreach (var game in subset)
{
Console.WriteLine("Item: {0}", game);
}
Console.WriteLine;
}
Как видите, построение выражения запроса LINQ с применением методов класса
Enumerable
напрямую приводит к намного более многословному запросу, чем в случае использования операций запросов С#. Кроме того, поскольку методы
Enumerable
требуют передачи делегатов в качестве параметров, обычно необходимо писать лямбда-выражения, чтобы обеспечить обработку входных данных внутренней целью делегата.
Построение выражений запросов с использованием типа Enumerable и анонимных методов
Учитывая, что лямбда-выражения C# — это просто сокращенный способ работы с анонимными методами, рассмотрим третье выражение запроса внутри вспомогательного метода
QueryStringsWithAnonymousMethods
:
static void QueryStringsWithAnonymousMethods
{
Console.WriteLine("***** Using Anonymous Methods *****");
Такой вариант выражения запроса оказывается еще более многословным из-за создания вручную делегатов
Func<>
, применяемых методами
Where
,
OrderBy
и
Select
класса
Enumerable
. Положительная сторона данного подхода связана с тем, что синтаксис анонимных методов позволяет заключить всю обработку, выполняемую делегатами, в единственное определение метода. Тем не менее, этот метод функционально эквивалентен методам
QueryStringsWithEnumerableAndLambdas
и
QueryStringsWithOperators
, созданным в предшествующих разделах.
Построение выражений запросов с использованием типа Enumerable и низкоуровневых делегатов
Наконец, если вы хотите строить выражение запроса с применением многословного подхода, то можете отказаться от использования синтаксиса лямбда-выражений и анонимных методов и напрямую создавать цели делегатов для каждого типа
Func<>
. Ниже показана финальная версия выражения запроса, смоделированная внутри нового типа класса по имени
VeryComplexQueryExpression
:
class VeryComplexQueryExpression
{
public static void QueryStringsWithRawDelegates
{
Console.WriteLine("***** Using Raw Delegates *****");