Язык программирования C#9 и платформа .NET5
class LINQBasedFieldsAreClunky{private static string[] currentVideoGames ={"Morrowind", "Uncharted 2","Fallout 3", "Daxter", "System Shock 2"};<b> // Здесь нельзя использовать неявную типизацию!</b><b> // Тип subset должен быть известен!</b>private IEnumerable<string> subset =from g in currentVideoGameswhere g.Contains(" ")orderby gselect g;public void PrintGames(){foreach (var item in subset){Console.WriteLine(item);}}}Запросы LINQ часто определяются внутри области действия метода или свойства. Кроме того, для упрощения программирования результирующий набор будет храниться в неявно типизированной локальной переменной, использующей ключевое слово
. Вспомните из главы 3, что неявно типизированные переменные не могут применяться для определения параметров, возвращаемых значений, а также полей класса или структуры.varИтак, вполне вероятно, вас интересует, каким образом возвратить результат запроса внешнему коду. Ответ: в зависимости от обстоятельств. Если у вас есть результирующий набор, состоящий из строго типизированных данных, такой как массив строк или список
объектовList<T>, тогда вы могли бы отказаться от использования ключевого словаCarи указать подходящий типvarлибоIEnumerable<T>(т.к.IEnumerableрасширяетIEnumerable<T>). Ниже приведен пример классаIEnumerableв новом проекте консольного приложения по имениProgram:LinqRetValuesusing System;using System.Collections.Generic;using System.Linq;Console.WriteLine("***** LINQ Return Values *****\n");IEnumerable<string> subset = GetStringSubset();foreach (string item in subset){Console.WriteLine(item);}Console.ReadLine();static IEnumerable<string> GetStringSubset(){string[] colors = {"Light Red", "Green", "Yellow", "Dark Red", "Red", "Purple"};// Обратите внимание, что subset является// совместимым с IEnumerable<string> объектом.IEnumerable<string> theRedColors =from c in colors where c.Contains("Red") select c;return theRedColors;}Результат выглядит вполне ожидаемо:
Light RedDark RedRedВозвращение результатов LINQ посредством немедленного выполнения
Рассмотренный пример работает ожидаемым образом только потому, что возвращаемое значение
и запрос LINQ внутри этого метода были строго типизированными. Если применить ключевое словоGetStringSubset()для определения переменнойvar, то возвращать значение будет разрешено, только если метод по-прежнему прототипирован с возвращаемым типомsubset(и если неявно типизированная локальная переменная на самом деле совместима с указанным возвращаемым типом).IEnumerable<string>Поскольку оперировать с типом
несколько неудобно, можно задействовать немедленное выполнение. Скажем, вместо возвращенияIEnumerable<T>можно было бы возвратить простоIEnumerable<string>при условии трансформации последовательности в строго типизированный массив. Именно такое действие выполняет новый метод классаstring[]:Programstatic string[] GetStringSubsetAsArray(){string[] colors = {"Light Red", "Green","Yellow", "Dark Red", "Red", "Purple"};var theRedColors = from c in colors where c.Contains("Red") select c;// Отобразить результаты в массив.return theRedColors.ToArray();}В таком случае вызывающий код совершенно не знает, что полученный им результат поступил от запроса LINQ, и просто работает с массивом строк вполне ожидаемым образом. Вот пример:
foreach (string item in GetStringSubsetAsArray()){Console.WriteLine(item);}Немедленное выполнение также важно при попытке возвратить вызывающему коду результаты проецирования LINQ. Мы исследуем эту тему чуть позже в главе. А сейчас давайте посмотрим, как применять запросы LINQ к обобщенным и необобщенным объектам коллекций.