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

ЖАНРЫ

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

using 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 Red

Dark Red

Red

Возвращение результатов LINQ посредством немедленного выполнения

Рассмотренный пример работает ожидаемым образом только потому, что возвращаемое значение

GetStringSubset
и запрос LINQ внутри этого метода были строго типизированными. Если применить ключевое слово
var
для определения переменной
subset
, то возвращать значение будет разрешено, только если метод по-прежнему прототипирован с возвращаемым типом
IEnumerable<string>
(и если неявно типизированная локальная переменная на самом деле совместима с указанным возвращаемым типом).

Поскольку оперировать с типом

IEnumerable<T>
несколько неудобно, можно задействовать немедленное выполнение. Скажем, вместо возвращения
IEnumerable<string>
можно было бы возвратить просто
string[]
при условии трансформации последовательности в строго типизированный массив. Именно такое действие выполняет новый метод класса
Program
:

static 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 к обобщенным и

необобщенным объектам коллекций.

Применение запросов LINQ к объектам коллекций

Помимо извлечения результатов из простого массива данных выражения запросов LINQ могут также манипулировать данными внутри классов из пространства имен

System.Collections.Generic
, таких как
List<T>
. Создайте новый проект консольного приложения по имени
ListOverCollections
и определите базовый класс
Car
, который поддерживает текущую скорость, цвет, производителя и дружественное имя:

namespace LinqOverCollections

{

class Car

{

public string PetName {get; set;} = "";

public string Color {get; set;} = "";

public int Speed {get; set;}

public string Make {get; set;} = "";

}

}

Теперь определите внутри операторов верхнего уровня локальную переменную типа

List<T>
для хранения элементов типа
Car
и с помощью синтаксиса инициализации объектов заполните список несколькими новыми объектами
Car
:

using System;

using System.Collections;

using System.Collections.Generic;

using System.Linq;

using LinqOverCollections;

Console.WriteLine("***** LINQ over Generic Collections *****\n");

// Создать список List<> объектов Car.

List<Car> myCars = new List<Car> {

new Car{ PetName = "Henry", Color = "Silver", Speed = 100, Make = "BMW"},

new Car{ PetName = "Daisy", Color = "Tan", Speed = 90, Make = "BMW"},

new Car{ PetName = "Mary", Color = "Black", Speed = 55, Make = "VW"},

new Car{ PetName = "Clunker", Color = "Rust", Speed = 5, Make = "Yugo"},

new Car{ PetName = "Melvin", Color = "White", Speed = 43, Make = "Ford"}

};

Console.ReadLine;

Доступ к содержащимся в контейнере подобъектам

Применение запроса LINQ к обобщенному контейнеру ничем не отличается от такого же действия в отношении простого массива, потому что LINQ to Objects может использоваться с любым типом, реализующим интерфейс

IEnumerable<T>
. На этот раз цель заключается в построении выражения запроса для выборки из списка
myCars
только тех объектов
Car
, у которых значение скорости больше
55
.

После получения подмножества на консоль будет выведено имя каждого объекта

Car
за счет обращения к его свойству
PetName
. Предположим, что определен следующий вспомогательный метод (принимающий параметр
List<Car>
), который вызывается в операторах верхнего уровня:

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