Добавил:
Upload Опубликованный материал нарушает ваши авторские права? Сообщите нам.
Вуз: Предмет: Файл:
Лекции по ООП (язык C#).pdf
Скачиваний:
190
Добавлен:
16.05.2015
Размер:
1.54 Mб
Скачать

Чернов Э. А.

- 97 -

Лекции по языку C# v 2.3

static void Main()

{

MyClass mc = new MyClass();

foreach (string st in mc) Console.WriteLine(st + " "); Console.ReadKey();

}

}

При выполнении этой программы получается следующий результат.

Как видите, выполнено последовательное обращение к элементам массива strs в объекте mc класса MyClass.

Рассмотрим эту программу более подробно. Во-первых, обратите внимание на то, что в классе MyClass не указывается IEnumerator в качестве реализуемого интерфейса. При создании итератора компилятор реализует этот интерфейс автоматически. И, во-вторых, обратите особое внимание на метод GetEnumerator (), который ради удобства приводится ниже еще раз.

LINQ

LINQ (Language INtegrated Query – Язык интегрированных запросов) - это встроенный в C# язык запросов, позволяющий извлекать и обрабатывать данные из различных источников, которые могут иметь различные форматы данных.

LINQ - технология Microsoft, предназначенная для поддержки запросов к данным всех типов на уровне языка. Запросы могут выполняться для массивов и коллекций в памяти, базам данных, документам XML и другим источникам информации.

Работа с базами данных создает специфические проблемы. Не обнаруживаются:

Неправильные ссылки на поля базы данных.

Наличие кода базы данных, который не проверяется во время компиляции,

Разница между типами базы данных и типами данных в языке, на котором написана программа.

LINQ включает в себя около 50 стандартных операций запросов, разделяемых на 2 большие группы - отложенные операции (выполняются не во время инициализации, а только при их вызове) и не отложенные операции (выполняются сразу).

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

Запросы могут направляться к источникам данных, для которых реализованы ин-

терфейсы IEnumerable<T> и IQueryable<T>. Интерфейс IEnumerable<T> предна-

Чернов Э. А.

- 98 -

Лекции по языку C# v 2.3

значен для реализации запросов к массивам и находящимся в памяти коллекциям данных, который предназначен для удаленных источников данных, а интерфейс IQueryable<T> позволяет адресовать запросы Link базе данных Microsoft SQL Server. С помощью объекта класса ObjectQuery<T> можно оформить запрос, который возвратит коллекцию типизированных объектов.

Возврат запроса может также переменной типа var. Такая переменная может содержать набор строк из таблицы.

Ниже приведен пример программы, в которой объявлен и инициализирован массив целых чисел, а затем с помощью запроса из массива выбираются числа, меньшие

16.

static void Main()

{

// Массив целых чисел.

int [ ] Ints = {7, 16, 27, 15, 4, 1, 3, 92, 2 };

// Простой запрос.

 

var MyQry =

// Неявно типизированный запрос

from num in Ints

// Переменная диапазона (num) и где искать

where num < 16

// Условие для поиска

select num;

// Выполнить запрос

// Просмотр результатов выполнения запроса.

foreach (var n in MyQry)

{

 

Console.Write( "{0}

", n);

}

 

Console.ReadKey();

 

}

Вывод программы имеет вид:

Вместо строки var MyQry = можно записать IEnumerable<int> MyQry=. Результат не изменится, поскольку указанный интерфейс для массивов реализуется автоматически.

Структура запроса содержит

Имя запроса. Тип для имени задается либо var, либо IEnumerable<T>, либо IQueryable<T>. После имени записывается знак равенства.

Конструкция from in. После слова from указывается произвольное имя (в пример num, оно задает диапазон просмотра, а слово in задает источник для поиска (в данном случае массив Ints).

Команда select.

Замечание 1: Хотя в примере и рассмотрен типовой запрос, на практике можно применять элементы запроса индивидуально, без связи с другими элементами.

Замечание 2: При использовании для типа имени интерфейса IEnumerable<T> требуется указать имя для <T>, это не требуется при указании типа var.

Замечание 3: Многие команды LINQ являются «отложенными» (например, команда select), то есть они выполняются только тогда, когда начинается перечисле-

Чернов Э. А.

- 99 -

Лекции по языку C# v 2.3

ние результатов реализации запроса. Достаточно часто это выполняется с помощью цикла foreach. Поэтому, если запрос был сформулирован неправильно, то это будет обнаружено только при перечислении результатов запроса и будет вызвана исключительная ситуация.

Замечание 4: Команда select (соответственно и метод Select) применима только для объектов, приведенных к типу перечисления.

Примечание: Для формирования последовательности целых чисел можно воспользоваться функцией Range, которая генерирует последовательность целых чисел.

Список аргументов этой функции состоит из двух значений: первый параметр start задает начальной значение последовательности, а второй параметр count задает количество членов последовательности. Ниже представлен пример оформления этой функции:

var seq =Enumerable.Range( 5,10);

foreach (int val in seq) Console.Write(" {0}", val);

Приведенный пример генерирует последовательность:

Ниже приведен пример программы, которая запрашивает ввод строки целых чисел, преобразует числа, введенные в виде строки, в числовое представление, сортирует их и выводит на экран.

static void Main()

{

Console.WriteLine("Введите целые числа через пробел"); string InStr = Console.ReadLine();

string [ ] MyInts = InStr.Split(' ');// Расщепление на массив строк

// Преобразуем массива строк и сортировка чисел по возрастанию int [ ] nums = MyInts.Select(x => int.Parse(x)).OrderBy(y => y).ToArray(); foreach (int n in nums)

{

Console.Write("{0} ",n);

}

Console.ReadKey();

}

Пример выполнения программы ниже:

Вместо команд запроса можно применять методы. В этом примере вместо команды select применен метод Select (с лямбда-выражением), вместо where можно применять метод Where (с лямбда-выражением) и т. д. Эти различия носят названия синтаксиса запросов и синтаксиса методов. Ниже приведен пример оформления запроса обоими методами.

string[ ] names = {"Андрей", "Сергей", "Иван", "Артем", "Леопольд", "Наталья", "Оксана", "Федор"};

// Синтаксис методов (отсутствует from)

Чернов Э. А.

- 100 -

Лекции по языку C# v 2.3

IEnumerable<string> sequence = names

.Where(n => n.Length < 6)

.Select(n => n); // Обратите внимание на точки

// Синтаксис запросов

IEnumerable<string> sequence = from n in names where n.Length < 6

select n; // Все команды из строчных букв

foreach (string name in sequence)

{

Console.WriteLine("{0}", name);

}

Независимо от выбранного метода будет выведено:

Грамматика выражений запросов

Выражения запросов должны подчиняться перечисленным ниже правилам:

1.Выражение должно начинаться с конструкции from.

2.Остальная часть выражения может содержать ноль или более конструкций from, let или where. КонструкцияT fromT — это генератор, который объявляет одну или более переменных диапазона, перечисляющих последовательность или соединение нескольких последовательностей. КонструкцияT letT представляет переменную диапазона и присваивает ей значение.

КонструкцияT whereT фильтрует элементы из входной последовательности или соединения несколько входных последовательностей в выходную последовательность.

3.Остальная часть выражения запроса может затем включать конструкцию orderby, содержащую одно или более полей сортировки с необязательным направлением упорядочивания. Направлением может бытьT ascending (по воз-

растанию)T или Tdescending (по убыванию)T.

4.Затем в оставшейся части выражения может идти конструкция select или group.

5.Наконец в оставшейся части выражения может следовать необязательная конструкция продолжения. Такой конструкцией может быть либо into, ноль или более конструкций join, или же другая повторяющаяся последовательность перечисленных элементов, начиная с конструкций из правила 2. КонструкцияT intoT направляет результаты запроса в воображаемую выходную последовательность, которая служит конструкцией from для последующих выражения запросов, начиная с конструкций из правила 2.

Если сформировано синтаксически правильное выражение запроса, как компилятор транслирует это выражение запроса в код C#, используя синтаксис методов. По этой причине далее рассматривается, в основном, синтаксис методов.