
- •Введение
- •Сравнение языков С++ и C#
- •Логические выражения
- •Функции для ввода и вывода в языке C#
- •Управление форматом числовых данных:
- •Обработка исключительных ситуаций
- •Методы и модификаторы параметров
- •Неявно типизированные переменные
- •Понятие класса
- •Свойства
- •Индексаторы
- •Одномерные индексаторы
- •Многомерные индексаторы
- •Перегрузка методов
- •Перегрузка знаков операций
- •Наследование
- •Виртуальные функции
- •Работа с файлами
- •Работа с каталогами
- •Абстрактный класс FileSystemInfo
- •Класс DirectoryInfo
- •Сериализация
- •FileSystemWatcher – отслеживание событий, связанных с файлами
- •Обобщения (шаблоны)
- •Интерфейсы
- •Коллекции
- •LINQ
- •Грамматика выражений запросов
- •Синтаксис запросов
- •Проекция и фильтрация
- •Упорядочение
- •Агрегирующие запросы
- •Операции с коллекциями
- •Операция Concat
- •Операция Union
- •Преобразование
- •Объединение последовательностей
- •FirstOrDefault
- •Группировка
- •Групповая адресация
- •Обработка событий
- •Групповое преобразование делегируемых методов
- •Применение методов экземпляра в качестве делегатов
- •Групповая адресация
- •Ковариантность и контравариантность
- •Класс System. Delegate
- •Назначение делегатов
- •Анонимные функции
- •Анонимные методы
- •Передача аргументов анонимному методу
- •Возврат значения из анонимного метода
- •Применение внешних переменных в анонимных методах
- •Лямбда-выражения
- •Лямбда-оператор
- •Одиночные лямбда-выражения
- •Блочные лямбда-выражения
- •События
- •Пример групповой адресации события
- •Применение аксессоров событий
- •Разнообразные возможности событий
- •Применение анонимных методов и лямбда-выражений вместе с событиями
- •Рекомендации по обработке событий в среде .NET Framework
- •Применение делегатов EventHandler<TEventArgs> и EventHandler
- •Практический пример обработки событий

Чернов Э. А. |
- 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#, используя синтаксис методов. По этой причине далее рассматривается, в основном, синтаксис методов.