Анонс обучающего курса на платформе 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 типов операций: агрегация, преобразование, конкатенация, элемент, множество, генерация, группирование, соединение, упорядочивание, проекция, разбиение, ограничение, квантификатор и эквивалентность.