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

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 163 164 165 166 167 168 169 170 171 ... 407
работе c LINQ вам редко (если вообще когда-либо) потребуется вручную строить собственные расширяющие методы. Тем не менее, создавая выражения запросов LINQ, вы на самом деле будете применять многочисленные расширяющие методы, уже определенные разработчиками из Microsoft. Фактически каждая операция запроса LINQ в C# представляет собой сокращенную запись для ручного вызова лежащего в основе расширяющего метода, который обычно определен в служебном классе System.Linq.Enumerable.

Анонимные типы

Последним средством языка С#, описание которого здесь кратко повторяется, являются анонимные типы, рассмотренные в главе 11. Данное средство может использоваться для быстрого моделирования "формы" данных, разрешая компилятору генерировать на этапе компиляции новое определение класса, которое основано на предоставленном наборе пар "имя-значение". Вспомните, что результирующий тип составляется с применением семантики на основе значений, а каждый виртуальный метод System.Object будет соответствующим образом переопределен. Чтобы определить анонимный тип, понадобится объявить неявно типизированную переменную и указать форму данных с использованием синтаксиса инициализации объектов:

// Создать анонимный тип, состоящий из еще одного анонимного типа.

var purchaseItem = new {

  TimeBought = DateTime.Now,

  ItemBought =

    new {Color = "Red", Make = "Saab", CurrentSpeed = 55},

  Price = 34.000};

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

Роль LINQ

На этом краткий обзор средств языка С#, которые позволяют LINQ делать свою работу, завершен. Однако важно понимать, зачем вообще нужен язык LINQ. Любой разработчик программного обеспечения согласится с утверждением, что значительное время при программировании тратится на получение и манипулирование данными. Когда говорят о "данных", на ум немедленно приходит информация, хранящаяся внутри реляционных баз данных. Тем не менее, другими популярными местоположениями для данных являются документы XML или простые текстовые файлы.

Данные могут находиться в многочисленных местах помимо указанных двух распространенных хранилищ информации. Например, пусть имеется массив или обобщенный тип List<T>, содержащий 300 целых чисел, и требуется получить подмножество, которое удовлетворяет заданному критерию (например, только четные или нечетные числа, только простые числа, только неповторяющиеся числа больше 50). Или, возможно, при использовании API-интерфейсов рефлексии необходимо получить в массиве элементов Туре только описания метаданных для каждого класса, производного от какого-то родительского класса. На самом деле данные находятся повсюду.

До появления версии .NET 3.5 взаимодействие с отдельной разновидностью данных требовало от программистов применения совершенно несходных API-интерфейсов. В табл. 13.1 описаны некоторые популярные API-интерфейсы, используемые для доступа к разнообразным типам данных (наверняка вы в состоянии привести и другие примеры).

Разумеется, с такими подходами к манипулированию данными не связано ничего плохого. В сущности, вы можете (и будете) работать напрямую с ADO.NET, пространствами имен XML, службами рефлексии и разнообразными типами коллекций. Однако основная проблема заключается в том, что каждый из API-интерфейсов подобного рода является "самостоятельным островком", трудно интегрируемым с другими. Правда, можно (например) сохранить объект DataSet из ADO.NET в документ XML и затем манипулировать им посредством пространств имен System.xml, но все равно манипуляции данными остаются довольно асимметричными.

В рамках API-интерфейса LINQ была предпринята попытка предложить программистам согласованный, симметричный способ получения и манипулирования "данными" в широком смысле этого понятия. Применяя LINQ, прямо внутри языка программирования C# можно создавать конструкции, которые называются выражениями запросов. Такие выражения запросов основаны на многочисленных операциях запросов, которые намеренно сделаны похожими внешне и по поведению (но не идентичными) на выражения SQL.

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

LINQ to Objects. Этот термин относится к действию по применению запросов LINQ к массивам и коллекциям.

LINQ to XML. Этот термин относится к действию по использованию LINQ для манипулирования и запрашивания документов XML.

LINQ to Entities. Этот аспект LINQ позволяет использовать запросы LINQ внутри API-интерфейса ADO.NET Entity Framework (EF) Core.

Parallel LINQ (PLINQ). Этот аспект делает возможной параллельную обработку данных, возвращаемых из запроса LINQ.

В настоящее время LINQ является неотъемлемой частью библиотек базовых классов .NET Core, управляемых языков и самой среды Visual Studio.

Выражения LINQ строго типизированы

 Важно также отметить, что выражение запроса LINQ (в отличие от традиционного оператора SQL) строго типизировано. Следовательно, компилятор C# следит за этим и гарантирует, что выражения оформлены корректно с точки зрения синтаксиса. Инструменты вроде Visual Studio могут применять метаданные для поддержки удобных средств, таких как IntelliSense, автозавершение и т.д.

Основные сборки LINQ

 Для работы с LINQ to Objects вы должны обеспечить импортирование пространства имен System.Linq в каждом файле кода С#, который содержит запросы LINQ. В противном случае возникнут проблемы. Удостоверьтесь, что в каждом файле кода, где используется LINQ, присутствует следующий оператор using:

using System.Linq;

Применение запросов LINQ к элементарным массивам

Чтобы начать исследование LINQ to Objects, давайте построим приложение, которое будет применять запросы LINQ к разнообразным объектам типа массива. Создайте новый проект консольного приложения под названием LinqOverArray и определите в классе Program статический вспомогательный метод по имени QueryOverStrings(). Внутри метода создайте массив типа string, содержащий несколько произвольных элементов (скажем, названий видеоигр). Удостоверьтесь в том, что хотя бы два элемента содержат числовые значения и несколько элементов включают внутренние пробелы:

static void QueryOverStrings()

{

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

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

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

}

Теперь модифицируйте файл Program.cs с целью вызова метода QueryOver Strings():

Console.WriteLine("***** Fun with LINQ to Objects *****n");

QueryOverStrings();

Console.ReadLine();

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

1 ... 163 164 165 166 167 168 169 170 171 ... 407
На этой странице вы можете бесплатно читать книгу Язык программирования C#9 и платформа .NET5 - Эндрю Троелсен бесплатно.

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