Класс Enumerable LINQ

ОГЛАВЛЕНИЕ

В качестве части работы над недавним программным проектом мне пришлось создавать случайным образом упорядоченный список целых чисел из интервала от 1 до 100. Да, очевидно, что это базовая проблема информатики типа 101. Исходно я использовал то же решение, которое написал в школьном классе в 1985 году, используя множество циклов, сравнений, датчиков случайных чисел и несколько массивов. Но теперь, в эпоху декларативного программирования, такое решение меня очень смущало.

После некоторого исследования мне удалось свести задачу всего лишь к двум строкам кода.

Dim rnd As New System.Random()
Dim numbers = Enumerable.Range(1, 100). _
  OrderBy(Function() rnd.Next)

После выполнения этих двух строк переменная numbers содержала целые числа из интервала от 1 до 100 в случайном порядке.

Поведение этого простого, но элегантного решения опирается на класс System.Linq.Enumerable, обеспечивающий несколько десятков совместно используемых методов, которые дают возможность манипулировать данными в любом классе, реализующем интерфейс IEnumerable(Of T). Кроме того, как видно из данного примера, эти методы могут также создавать новые коллекции данных.

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

В качестве примера я создал простое приложение на базе Windows®. В этом проекте я добавил простые классы, представляющие данные о клиентах, категориях и продуктах, и добавил класс с именем SimpleDataContext, наполняющий экземпляры этих классов данными из примера Northwind базы данных SQL Server®. Помимо этого, данный класс обеспечивает свойства с именами Customers, Categories и Products; каждое из них содержит, соответственно, общие экземпляры List of Customer, Category и Product. (Хотя можно было бы использовать конструктор LINQ к SQL для создания «настоящего» класса DataContext, такой подход не позволил бы мне продемонстрировать методы расширения класса Enumerable: когда описанные методы вызываются в контексте LINQ к SQL, в действительности вызываются методы расширения класса Queryable поставщика LINQ к SQL, которые имеют такую же сигнатуру, как и приводимые здесь методы. Хотя такие примеры продемонстрировали бы такое же поведение, в них не использовался бы класс Enumerable.) Я настойчиво рекомендую загрузить пример приложения и воспользоваться этим приложением — код будет гораздо понятнее, если вы сможете экспериментировать с ним напрямую, а не просто читать статью.

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

Обратите внимание, что примеры, как правило, дают возможность Visual Basic® логически выводить типы данных вместо того, чтобы иметь код, указывающий тип возвращаемого значения для вызовов, обращенных к методам расширения класса Enumerable. Кроме этого, пример опирается на пример базы данных Northwind, установленной в среде SQL Express. Если потребуется выполнить пример, необходимо будет либо сделать копию этой среды, либо изменить пример приложения.