Категории
Самые читаемые
onlinekniga.com » Компьютеры и Интернет » Программирование » Полное руководство. С# 4.0 - Шилдт Герберт

Полное руководство. С# 4.0 - Шилдт Герберт

Читать онлайн Полное руководство. С# 4.0 - Шилдт Герберт

Шрифт:

-
+

Интервал:

-
+

Закладка:

Сделать
1 ... 142 143 144 145 146 147 148 149 150 ... 188
Перейти на страницу:

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

Рассмотрим другой пример. Но сначала приведем еще раз запрос из представленного ранее примера применения оператора join.var inStockList = from item in items join entry in statusList on item.ItemNumber equals entry.ItemNumber select new Temp(item.Name, entry.InStock);

По этому запросу формируется последовательность, состоящая из объектов, инкапсулирующих наименование товара и состояние его запасов на складе. Вся эта информация получается путем объединения двух источников данных: items и statusList.Ниже приведен переделанный вариант данного запроса, в котором вместо синтаксиса,предусмотренного в C# для запросов, используется метод запроса Join().// Использовать метод запроса Join() для составления списка// наименований товаров и состояния их запасов на складе.var inStockList = items.Join(statusList, k1 => k1.ItemNumber, k2 => k2.ItemNumber, (k1, k2) => new Temp(k1.Name, k2.InStock) );

В данном варианте именованный класс Temp используется для хранения результирующего объекта, но вместо него можно воспользоваться анонимным типом. Такойвариант запроса приведен ниже.var inStockList = items.Join(statusList, k1 => k1.ItemNumber, k2 => k2.ItemNumber, (k1, k2) => new { k1.Name, k2.InStock} );Синтаксис запросов и методы запроса

Как пояснялось в предыдущем разделе, запросы в C# можно формировать двумяспособами, используя синтаксис запросов или методы запроса. Любопытно, что обаспособа связаны друг с другом более тесно, чем кажется, глядя на исходный код программы. Дело в том, что синтаксис запросов компилируется в вызовы методов запроса.Поэтому кодwhere х < 10

будет преобразован компилятором в следующий вызов.Where(х => х < 10)

Таким образом, оба способа формирования запросов в конечном итоге сходятся наодном и том же.

Но если оба способа оказываются в конечном счете равноценными, то какой из нихлучше для программирования на С#? В целом, рекомендуется чаще пользоваться синтаксисом запросов, поскольку он полностью интегрирован в язык С#, поддерживаетсясоответствующими ключевыми словами и синтаксическим конструкциями.Дополнительные методы расширения, связанные с запросами

Помимо методов, соответствующих операторам запроса, поддерживаемым в С#, имеется ряд других методов расширения, связанных с запросами и зачастую оказывающихпомощь в формировании запросов. Эти методы предоставляются в среде .NET Frameworkи определены для интерфейса IEnumerable в классе Enumerable. Ниже приведены наиболее часто используемые методы расширения, связанные с запросами. Многиеиз них могут перегружаться, поэтому они представлены лишь в самой общей форме.МетодОписаниеAll(predicate)Возвращает логическое значение true, если все элементы в последовательности удовлетворяют условию, задаваемому параметром predicateAny(predicate)Возвращает логическое значение true, если любой элемент в последовательности удовлетворяет условию, задаваемому параметром predicateAverage()Возвращает среднее всех значений в числовой последовательностиContains(value)Возвращает логическое значение true, если в последовательности содержится указанный объектCount()Возвращает длину последовательности, т.е. количество составляющих ее элементовFirst()Возвращает первый элемент в последовательностиLast()Возвращает последний элемент в последовательностиMax()Возвращает максимальное значение в последовательностиMin()Возвращает минимальное значение в последовательностиSum()Возвращает сумму значений в числовой последовательности

Метод Count() уже демонстрировался ранее в этой главе. А в следующей программе демонстрируются остальные методы расширения, связанные с запросами.// Использовать ряд методов расширения, определенных в классе Enumerable.using System;using System.Linq;class ExtMethods { static void Main() { int[] nums ={ 3, 1, 2, 5, 4 }; Console.WriteLine("Минимальное значение равно " + nums.Min()); Console.WriteLine("Максимальное значение равно " + nums.Max()); Console.WriteLine("Первое значение равно " + nums.First()); Console.WriteLine("Последнее значение равно " + nums.Last()); Console.WriteLine("Суммарное значение равно " + nums.Sum()); Console.WriteLine("Среднее значение равно " + nums.Average()); if(nums.All(n => n > 0)) Console.WriteLine("Все значения больше нуля."); if(nums.Any(n => (n % 2) == 0)) Console.WriteLine("По крайней мере одно значение является четным."); if(nums.Contains(3)) Console.WriteLine("Массив содержит значение 3."); }}

Вот к какому результату приводит выполнение этой программы.Минимальное значение равно 1Максимальное значение равно 5Первое значение равно 3Последнее значение равно 4Суммарное значение равно 15Среднее значение равно 3Все значения больше нуля.По крайней мере одно значение является четнымМассив содержит значение 3.

Методы расширения, связанные с запросами, можно также использовать в самомзапросе, основываясь на синтаксисе запросов, предусмотренном в С#. И в действительности это делается очень часто. Например, метод Average() используется в приведенной ниже программе для получения последовательности, состоящей только из техзначений, которые оказываются меньше среднего всех значений в массиве.// Использовать метод Average() вместе с синтаксисом запросов.using System;using System.Linq;class ExtMethods2 { static void Main() { int[] nums = { 1, 2, 4, 8, 6, 9, 10, 3, 6, 7 }; var ltAvg = from n in nums let x = nums.Average() where n < x select n; Console.WriteLine("Среднее значение равно " + nums.Average()); Console.Write("Значения меньше среднего: "); // Выполнить запрос и вывести его результаты. foreach(int i in ltAvg) Console.Write(i + " "); Console.WriteLine(); }}

При выполнении этой программы получается следующий результат.Среднее значение равно 5.6Значения меньше среднего: 1 2 4 3

Обратите особое внимание в этой программе на следующий код запроса.var ltAvg = from n in nums let x = nums.Average() where n < x select n;

Как видите, переменной x в операторе let присваивается среднее всех значенийв массиве nums. Это значение получается в результате вызова метода Average() длямассива nums.Режимы выполнения запросов: отложенный и немедленный

В LINQ запросы выполняются в двух разных режимах: немедленном и отложенном.Как пояснялось ранее в этой главе, при формировании запроса определяется ряд правил, которые не выполняются вплоть до оператора цикла foreach. Это так называемое отложенное выполнение.

Но если используются методы расширения, дающие результат, отличающийся отпоследовательности, то запрос должен быть выполнен для получения этого результата. Рассмотрим, например, метод расширения Count(). Для того чтобы этот методвозвратил количество элементов в последовательности, необходимо выполнить запрос, и это делается автоматически при вызове метода Count(). В этом случае имеетместо немедленное выполнение, когда запрос выполняется автоматически для получениятребуемого результата. Таким образом, запрос все равно выполняется, даже если он неиспользуется явно в цикле foreach.

Ниже приведен простой пример программы для получения количества положительных элементов, содержащихся в последовательности.// Использовать режим немедленного выполнения запроса.using System;using System.Linq;class ImmediateExec { static void Main() { int[] nums = { 1, -2, 3, 0, -4, 5 }; // Сформировать запрос на получение количества // положительных значений в массиве nums. int len = (from n in nums where n > 0 select n).Count (); Console.WriteLine("Количество положительных значений в массиве nums: " + len); }}

Эта программа дает следующий результат.Количество положительных значений в массиве nums: 3

Обратите внимание на то, что цикл foreach не указан в данной программе явнымобразом. Вместо этого запрос выполняется автоматически благодаря вызову методарасширения Count().

1 ... 142 143 144 145 146 147 148 149 150 ... 188
Перейти на страницу:
На этой странице вы можете бесплатно читать книгу Полное руководство. С# 4.0 - Шилдт Герберт.
Комментарии