Чтение онлайн

ЖАНРЫ

Язык программирования C#9 и платформа .NET5
Шрифт:

Исходя из предположения, что из массива нужно получить только элементы, содержащие внутри себя пробел, и представить их в алфавитном порядке, можно построить следующее выражение запроса LINQ:

static void QueryOverStrings

{

// Предположим, что имеется массив строк.

string[] currentVideoGames = {"Morrowind", "Uncharted 2",

"Fallout 3", "Daxter", "System
Shock 2"};

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

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

IEnumerable<string> subset =

from g in currentVideoGames

where g.Contains(" ")

orderby g

select g;

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

foreach (string s in subset)

{

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

}

}

Обратите внимание, что в созданном здесь выражении запроса применяются операции

from
,
in
,
where
,
orderby
и
select
языка LINQ. Формальности синтаксиса выражений запросов будут подробно излагаться далее в главе. Тем не менее, даже сейчас вы в состоянии прочесть данный оператор примерно так: "предоставить мне элементы из
currentVideoGames
, содержащие пробелы, в алфавитном порядке".

Каждому элементу, который соответствует критерию поиска, назначается имя

g
(от "game"), но подошло бы любое допустимое имя переменной С#:

IEnumerable<string> subset =

from game in currentVideoGames

where game.Contains(" ")

orderby game

select game;

Возвращенная последовательность сохраняется в переменной по имени

subset
, которая имеет тип, реализующий обобщенную версию интерфейса
IEnumerable<T>
, где
Т
— тип
System.String
(в конце концов, вы запрашиваете массив элементов
string
). После получения результирующего набора его элементы затем просто выводятся на консоль с использованием стандартной конструкции
foreach
. Запустив приложение, вы получите следующий вывод:

***** Fun with LINQ to Objects *****

Item: Fallout 3

Item: System Shock 2

Item: Uncharted 2

Решение с использованием расширяющих методов

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

QueryOverStringsWithExtensionMethods
со следующим кодом:

static void QueryOverStringsWithExtensionMethods

{

// Пусть имеется массив строк.

string[] currentVideoGames = {"Morrowind", "Uncharted 2",

"Fallout 3", "Daxter", "System Shock 2"};

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

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

IEnumerable<string> subset =

currentVideoGames.Where(g => g.Contains(" "))

.OrderBy(g => g).Select(g => g);

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

foreach (string s in subset)

{

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

}

}

Код здесь тот же, что и в предыдущем методе, кроме строк, выделенных полужирным. В них демонстрируется применение синтаксиса расширяющих методов, в котором для определения операций внутри каждого метода используются лямбда-выражения. Например, лямбда-выражение в методе

Where
определяет условие (содержит ли значение пробел). Как и в синтаксисе выражений запросов, используемая для идентификации значения буква произвольна; в примере применяется
v
для видеоигр (video game).

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

Решение без использования LINQ

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

if
и циклы
for
. Ниже приведен метод, который выдает тот же самый результат, что и
QueryOverStrings
, но в намного более многословной манере:

static void QueryOverStringsLongHand

{

// Предположим, что имеется массив строк.

string[] currentVideoGames = {"Morrowind", "Uncharted 2",

"Fallout 3", "Daxter", "System Shock 2"};

string[] gamesWithSpaces = new string[5];

for (int i = 0; i < currentVideoGames.Length; i++)

{

if (currentVideoGames[i].Contains(" "))

{

gamesWithSpaces[i] = currentVideoGames[i];

}

}

// Отсортировать набор.

Array.Sort(gamesWithSpaces);

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

foreach (string s in gamesWithSpaces)

{

if( s != null)

{

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

}

}

Console.WriteLine;

}

Несмотря на возможные пути улучшения метода

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

Поделиться с друзьями: