Рейтинговые книги
Читем онлайн Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 253 254 255 256 257 258 259 260 261 ... 642

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

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

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

IEnumerable<string> subset = from g in currentVideoGames

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

<b>ReflectOverQueryResults(subset);</b>

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

foreach (string s in subset)

{

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

}

Запустив приложение, легко заметить, что переменная subset в действительности представляет собой экземпляр обобщенного типа OrderedEnumerable&lt;TElement, ТКеу&gt; (представленного в коде 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&lt;string&gt; subset = currentVideoGames

    .Where(g =&gt; g.Contains(&quot; &quot;)) .OrderBy(g =&gt; g).Select(g =&gt; g);

<b>ReflectOverQueryResults(subset,&quot;Extension Methods&quot;);</b>

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

foreach (string s in subset)

{

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

}

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

(window.adrunTag = window.adrunTag || []).push({v: 1, el: 'adrun-4-390', c: 4, b: 390})

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

resultSet is of type: SelectIPartitionIterator`2

resultSet location: System.Linq

LINQ и неявно типизированные локальные переменные

Хотя в приведенной программе относительно легко выяснить, что результирующий набор может быть интерпретирован как перечисление объектов string (например, IEnumerable&lt;string&gt;), тот факт, что подмножество на самом деле имеет тип OrderedEnumerable&lt;TElement, ТКеу&gt;, не настолько ясен.

Поскольку результирующие наборы LINQ могут быть представлены с применением порядочного количества типов из разнообразных пространств имен LINQ, было бы утомительно определять подходящий тип для хранения результирующего набора. Причина в том, что во многих случаях лежащий в основе тип не очевиден и даже напрямую не доступен в коде (и как вы увидите, в ряде ситуаций тип генерируется на этапе компиляции).

Чтобы еще больше подчеркнуть данное обстоятельство, ниже показан дополнительный вспомогательный метод, определенный внутри класса Program:

static void QueryOverInts()

{

  int[] numbers = {10, 20, 30, 40, 1, 2, 3, 8};

  // Вывести только элементы меньше 10.

  IEnumerable&lt;int&gt; subset = from i in numbers where i &lt; 10 select i;

  foreach (int i in subset)

  {

    Console.WriteLine(&quot;Item: {0}&quot;, i);

  }

  ReflectOverQueryResults(subset);

}

В рассматриваемом случае переменная subset имеет совершенно другой внутренний тип. На этот раз тип, реализующий интерфейс IEnumerable&lt;int&gt;, представляет собой низкоуровневый класс по имени WhereArrayIterator&lt;T&gt;:

Item: 1

Item: 2

Item: 3

Item: 8

***** Info about your query *****

resultSet is of type: WhereArrayIterator`1

resultSet location: System.Linq

Учитывая, что точный тип запроса LINQ не вполне очевиден, в первых примерах результаты запросов были представлены как переменная IEnumerable&lt;T&gt;, где Т — тип данных в возвращенной последовательности (string, int и т.д.). Тем не менее, ситуация по-прежнему довольно запутана. Чтобы еще больше все усложнить, стоит упомянуть, что поскольку интерфейс IEnumerable&lt;T&gt; расширяет необобщенный IEnumerable, получать результат запроса LINQ допускается и так:

1 ... 253 254 255 256 257 258 259 260 261 ... 642
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю бесплатно.
Похожие на Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю книги

Оставить комментарий