Анонс обучающего курса на платформе Stepik. Часть 3
Часто приходится слышать как люди, увидев код PascalАВС.NЕТ в точечной нотации, говорят: "А, тут LINQ используется...". И это зачастую совершенно неверно. Вот пример кода с точечной нотацией, который не имеет к LINQ никакого отношения:
## function Sum(Self: array of integer): integer; extensionmethod; begin Result := 0; foreach var n in Self do Result += n end; function Println(Self: array of integer): array of integer; extensionmethod; begin var n := Self.Length; Result := new integer[n]; for var i := 0 to n - 2 do begin Result[i] := Self[i]; Write(Self[i], ' ') end; Result[n - 1] := Self[n - 1]; Writeln(Self[n - 1]) end; var n := ReadInteger; var a := new integer[n]; a[0] := 1; a[1] := 3; for var i := 2 to n - 1 do a[i] := 3 * a[i - 2] + 5 * a[i - 1] - 4; Write(a.Println.Sum) { Результат работы программы: 10 1 3 14 75 413 2286 12665 70179 388886 2154963 2629485 }
Так что же такое LINQ на самом деле?
LINQ - сокращенное название технологии Microsoft LINQ to Objects библиотек .NET Framework. для доступа к данным, расположенным в памяти компьютера. Сам термин LINQ - аббревиатура Language INtegrated Query (интегрированный язык запросов). Используя LINQ, можно обращаться к последовательностям, а также к коллекциям данных, например, к спискам List, как к таблицам базы данных.
Традиционно данные из последовательностей извлекались путем перебора всех элементов в цикле foreach
. Использование LINQ предполагает создание запросов - фрагментов кода, описывающих данные, которые требуется извлечь без указания того, как это сделать.
Использование запросов LINQ дает следующие преимущества:
- запросы короткие, их удобно читать и легко понимать;
- запросы мощные, с их помощью можно производить сложную обработку данных;
- запросы могут переноситься в другие источники данных практически без изменения (они одинаковы для последовательностей, списков и т.д.).
Чем сложнее набор манипуляций с данными, тем больший выигрыш достигается с использованием запросов LINQ, объединенных в цепочки точечной нотации.
Технология LINQ включает около полусотни операций, разделяющихся на две группы - отложенные ("ленивые") операции и не отложенные операции (исполняются сразу). К группе не отложенных операций относятся получение свёрток (приведение данных к единственному значению - сумме, произведению, количеству и т.п.), выборка единственного элемента, преобразование к другому типу данных (последовательности в список List, массив или словарь), а также установление эквивалентности двух наборов данных.
Чтобы получить непосредственный доступ к методам LINQ, нужно либо подключить пространство имён System.Linq
, либо указывать его при каждом вызове метода. Для последовательностей в .NET нужно обращаться к классу Enumerable
.
## uses System.Linq; var s := Enumerable.Range(-3, 8); s.Println; // -3 -2 -1 0 1 2 3 4 s := Enumerable.Reverse(s); s.Print // 4 3 2 1 0 -1 -2 -3
## var s := System.Linq.Enumerable.Range(-3, 8); s.Println; // -3 -2 -1 0 1 2 3 4 s := System.Linq.Enumerable.Reverse(s); s.Print // 4 3 2 1 0 -1 -2 -3
Вызовы подобной длины приходится писать, например, в языке C#. Разработчики PascalАВС.NЕТ ввели множество дополнительных функций и методов расширения, позволяющих сделать работу с LINQ существенно удобнее.
## var s := Range(-3, 4); s.Println; // -3 -2 -1 0 1 2 3 4 s := s.Reverse; s.Print // 4 3 2 1 0 -1 -2 -3
Здесь Range
- уже не метод из LINQ, а функция PascalАВС.NЕТ. Если в .NET-методе второй параметр обозначал длину генерируемой последовательности, то в функции это верхняя граница диапазона данных. Сама же функция находится в системной библиотеке PABCSystem и является "обёрткой" для вызова метода .NET:
function Range(a, b: integer): sequence of integer; begin if b < a then Result := System.Linq.Enumerable.Empty&<integer> else Result := System.Linq.Enumerable.Range(a, b - a + 1); end;
В состав .NET LINQ входят 14 типов операций: агрегация, преобразование, конкатенация, элемент, множество, генерация, группирование, соединение, упорядочивание, проекция, разбиение, ограничение, квантификатор и эквивалентность.