KnigaRead.com/
KnigaRead.com » Компьютеры и Интернет » Базы данных » Язык программирования C#9 и платформа .NET5 - Троелсен Эндрю

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

На нашем сайте KnigaRead.com Вы можете абсолютно бесплатно читать книгу онлайн Троелсен Эндрю, "Язык программирования C#9 и платформа .NET5" бесплатно, без регистрации.
Перейти на страницу:

Модифицируйте код метода

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;
, проход по ним осуществляется одинаковым образом и они оба способны создавать список или массив своих значений.

***** 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 допускается и так:

Перейти на страницу:
Прокомментировать
Подтвердите что вы не робот:*