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

Чернов Э. А.

- 101 -

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

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

Выражения запросов в LINQ имеют множество конструкций, поэтому целесообразно их рассматривать по функциям.(пр)

Проекция и фильтрация

ОперацияT SelectT позволяет выбрать элементы выходной последовательности из входной коллекции. Типы входных и выходных элементов могут различаться. Например, если выходная коллекция состоит из объектов некоторого класса (типизированный набор данных), то на выходе можно получить как коллекцию объектов того же типа, так и просто список, содержащий значения одного из полей объекта.

Существуют два прототипа этой операции, которые описаны ниже: (пр)

Первый прототип Select

public static IEnumerable<S> Select<T, S>( this IEnumerable<T> source, Func<T, S> selector);

Этот прототип Select принимает входную последовательность и делегат методаселектора в качестве входных параметров, а возвращает объект, который при перечислении проходит по входной последовательности и выдает последовательность элементов типа S. Как упоминалось ранее, Т и S могут быть как одного, так и разных типов.

При вызове Select делегат метода-селектора передается в аргументе selector. Ме- тод-селектор должен принимать тип Т в качестве входного, где Т — тип элементов, содержащихся во входной последовательности, и возвращать элемент типа S. Операция Select вызовет метод-селектор для каждого элемента входной последовательности, передав ему этот элемент. Метод-селектор выберет интересующую часть входного элемента, создаст новый элемент — возможно, другого типа (даже анонимного) — и вернет его.

Второй прототип Select

public static IEnumerable<S> Select<T, S>(this IEnumerable<T> source, Func<T, int, S> selector);

В этом прототипе операции Select методу-селектору передается дополнительный целочисленный параметр. Это индекс, начинающийся с нуля, входного элемента во входной последовательности.

Пример выборки из списка объектов типа перечня профессий:

class Program

{

class Block

{

public string prof { get; set; } public string name { get; set; } public string secname { get; set; }

Чернов Э. А.

- 102 -

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

public int skil; public double wage;

public Block() { } // Конструктор пустой

public Block(string p, string s, string sn, int k, double w) // Конструктор с па-

раметрами

{

prof = p; name = s; secname = sn; skil = k;

wage = w;

}

}

static void Main(string[] args)

{

StreamReader file = new StreamReader("C:\\Temp\\blocks.txt", Encoding.Default);

string s; int sk; double wg;

string [ ] str;

Block blk = new Block(); List<Block> lst = new List<Block>();

//

while ((s = file.ReadLine()) != null)

{

str = s.Split(' ');

sk = int.Parse(str[2]);

wg = double.Parse(str[3]);

lst.Add(new Block(str[0], str[1], sk, wg));

}

Console.WriteLine("Начальный список");

foreach (Block bl in lst) // Вывод начального списка Console.WriteLine("{0,-12}\t{1,-8}\t{2}\t{3}",

bl.prof, bl.name, bl.skil, bl.wage); Console.WriteLine("\n Выборка по профессии");

// Синтаксис запроса метода (в Select задано поле для выборки) var blQuery = lst.Select(p => p.prof);// Возврат списка профессий foreach (var pr in blQuery)

{

Console.WriteLine(pr);

}

Console.ReadKey();

}

}

Результат выполнения программы имеет вид

Чернов Э. А.

- 103 -

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

Запрос можно видоизменить

var blQuery = lst.Select(p => p);// Возврат списка объектов типа Block

Но тогда для вывода поля требуется нотация с точкой: Console.WriteLine(pr.prof);

Можно выполнить фильтрацию списка. Например, для выборки из списка всех токарей фрагмент программы приобретает вид:

var blQuery = lst.Where(t => t.prof == "токарь");// Создается новый список Console.WriteLine("\n Список токарей");

foreach (var pr in blQuery)

{

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

}

Результат выполнения программы имеет вид:

Размером списка можно управлять. Для этого применяются конструкции

Take возвращает указанное количество элементов из входной последовательности, начиная с ее начала

TakeWhile возвращает элементы из входной последовательности, пока истинно некоторое условие, начиная с начала последовательности. Остальные входные элементы пропускаются.

Skip пропускает указанное количество элементов из входной последовательности, начиная с ее начала, и выводит остальные.

SkipWhile обрабатывает входную последовательность, пропуская элементы до тех пор, пока условие истинно, а затем выводит остальные в выходную последовательность.

Пример использования конструкции Take

var blQuery = lst.Where(t => t.prof == "токарь").Take(1);//

Из полученного списка выбирает первую позицию.

Ниже приведен пример выборки списка токарей с уровнем заданной зарплаты

var blQuery = lst.Where(t => t.prof == "токарь").TakeWhile(t =>t.wage<40);// Console.WriteLine("Список токарей с зарплатой меньше 40 тысяч руб."); foreach (var pr in blQuery)

Чернов Э. А.

- 104 -

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

{

Console.WriteLine(" {0} зарплата {1}",pr.name, pr.wage);

}

Результат выполнения программы имеет вид:

Аналогично применяются конструкции Skip и SkipWhile. В этом случае выполняется пропуск либо заданного количества позиций, либо пропуск осуществляется до тех пор, пока выполняется заданное условие.

Упорядочение

Упорядочение или сортировка позволяет реорганизовать получаемый список так, чтобы была упорядоченность по заданному полю. Упорядоченность может быть по возрастанию значений заданного поля (для строк упорядоченность выполняется по алфавиту), либо по убыванию значений поля. Упорядоченность по возрастанию устанавливается по умолчанию. Для упорядоченности по убыванию применяется ключевое слово descending. Конструкция для сортировки по возрастанию OrderBy. Для сортировки по убыванию OrderByDescending. Ниже приведен пример сортировки списка по фамилиям.

Console.WriteLine("\n Сортировка по фамилии\n"); var blQuery = lst.OrderBy(t => t.name);//

foreach (var pr in blQuery)

{

Console.WriteLine(" {0,-7}\t {1}",pr.name, pr.prof);

}

Результат выполнения программы имеет вид:

В некоторых случаях сортировки по одному полю недостаточно, например, при наличии однофамильцев. Тогда добавляется сортировка по второму полю с помощью конструкции ThenBy или ThenByDescending. Пример:

var blQuery = lst.OrderBy(t => t.name).ThenBy(t =>t.secname);// foreach (var pr in blQuery)

{

Console.WriteLine(" {0,-7}\t {1,-7}\t {2}",pr.name, pr.secname, pr.prof);

}

Результат выполнения программы имеет вид: