Console.WriteLine("Item: {0}", s);

    }

  }

  Console.WriteLine();

}

Несмотря на возможные пути улучшения метода QueryOverStringsLongHand(), факт остается фактом — запросы LINQ способны радикально упростить процесс извлечения новых подмножеств данных из источника. Вместо построения вложенных циклов, сложной логики if/else, временных типов данных и т.п. компилятор С# сделает всю черновую работу, как только вы создадите подходящий запрос LINQ.

<p id="AutBody_Root489">Выполнение рефлексии результирующего набора LINQ</p>

А теперь определите в классе Program дополнительный вспомогательный метод по имени ReflectOverQueryResults(), который выводит на консоль разнообразные детали о результирующем наборе LINQ (обратите внимание на параметр типа System.Object, позволяющий учитывать множество типов результирующих наборов):

static void ReflectOverQueryResults(object resultSet,

                                    string queryType = "Query Expressions")

{

  Console.WriteLine($"***** Info about your query using {queryType} *****");

  // Вывести тип результирующего набора

  Console.WriteLine("resultSet is of type: {0}", resultSet.GetType().Name);

  // Вывести местоположение результирующего набора

  Console.WriteLine("resultSet location: {0}",

                     resultSet.GetType().Assembly.GetName().Name);

}

Модифицируйте код метода QueryOverStrings() следующим образом:

// Построить выражение запроса для поиска

// в массиве элементов, содержащих пробел.

IEnumerable subset = from g in currentVideoGames

  where g.Contains(" ") orderby g select g;

ReflectOverQueryResults(subset);

// Вывести результаты.

foreach (string s in subset)

{

  Console.WriteLine("Item: {0}", s);

}

Запустив приложение, легко заметить, что переменная subset в действительности представляет собой экземпляр обобщенного типа OrderedEnumerable (представленного в коде CIL как OrderedEnumerable`2), который является внутренним абстрактным типом, находящимся в сборке System.Linq.dll:

***** Info about your query using Query Expressions*****

resultSet is of type: OrderedEnumerable`2

resultSet location: System.Linq

Внесите такое же изменение в код метода QueryOverStringsWithExtensionMethods(), но передав во втором параметре строку "Extension Methods":

// Построить выражение запроса для поиска

// в массиве элементов, содержащих пробел.

IEnumerable subset = currentVideoGames

    .Where(g => g.Contains(" ")) .OrderBy(g => g).Select(g => g);

ReflectOverQueryResults(subset,"Extension Methods");

// Вывести результаты.

foreach (string s in subset)

{

  Console.WriteLine("Item: {0}", s);

}

После запуска приложения выяснится, что переменная subset является экземпляром типа SelectIPartitionIterator. Но если удалить из запроса конструкцию Select(g=>g), то subset снова станет экземпляром типа OrderedEnumerable. Что все это значит? Для подавляющего большинства разработчиков немногое (если вообще что-либо). Оба типа являются производными от IEnumerable, проход по ним осуществляется одинаковым образом и они оба способны создавать список или массив своих значений.

***** Info about your query using Extension Methods *****

resultSet is of type: SelectIPartitionIterator`2

resultSet location: System.Linq

<p id="AutBody_Root490">LINQ и неявно типизированные локальные переменные</p>
Перейти на страницу:

Похожие книги