Вход/Регистрация
Полное руководство. С# 4.0
вернуться

Шилдт Герберт

Шрифт:

Ниже приведен простой пример программы для получения количества положи тельных элементов, содержащихся в последовательности. // Использовать режим немедленного выполнения запроса. 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.

Любопытно, что запрос из приведенной выше программы можно было бы сформи ровать и следующим образом. var posNums = from n in nums where n > 0 select n; int len = posNums.Count; // запрос выполняется здесь

В данном случае метод Count вызывается для переменной запроса. И в этот мо мент запрос выполняется для получения подсчитанного количества.

К числу других методов расширения, вызывающих немедленное выполнение за проса, относятся методы ТоАrray и ToList. Оба этих метода расширения опре делены в классе Enumerable. Метод ToArray возвращает результаты запроса в мас сиве, а метод ToList — результаты запроса в форме коллекции List. (Подробнее о коллекциях речь пойдет в главе 25.) В обоих случаях для получения результатов вы полняется запрос. Например, в следующем фрагменте кода сначала получается массив результатов, сформированных по приведенному выше запросу в переменной posNums, а затем эти результаты выводятся на экран. int[] pnums = posNum.ТоАrrау; // запрос выполняется здесь foreach(int i in pnums) Console.Write(i + " "); } Деревья выражений

Еще одним средством, связанным с LINQ, является дерево выражений, которое пред ставляет лямбда-выражение в виде данных. Это означает, что само лямбда-выражение нельзя выполнить, но можно преобразовать в исполняемую форму. Деревья выражений инкапсулируются в классе System.Linq.Expressions.Expression<TDelegate>.

Они оказываются пригодными в тех случаях, когда запрос выполняется вне програм мы, например средствами SQL в базе данных. Если запрос представлен в виде данных, то его можно преобразовать в формат, понятный для базы данных. Этот процесс вы полняется, например, средствами LINQ to SQL в интегрированной среде разработки Visual Studio. Таким образом, деревья выражений способствуют поддержке в C# раз личных баз данных.

Для получения исполняемой формы дерева выражений достаточно вызвать метод Compile, определенный в классе Expression. Этот метод возвращает ссылку, ко торая может быть присвоена делегату для последующего выполнения. А тип делегата может быть объявлен собственным или же одним из предопределенных типов деле гата Func в пространстве имен System. Две формы делегата Func уже упоминались ранее при рассмотрении методов запроса, но существует и другие его формы. Деревьям выражений присуще следующее существенное ограничение: они могут представлять только одиночные лямбда-выражения. С их помощью нельзя предста вить блочные лямбда-выражения.

Ниже приведен пример программы, демонстрирующий конкретное применение дерева выражений. В этой программе сначала создается дерево выражений, данные которого представляют метод, определяющий, является ли одно целое число множи телем другого. Затем это дерево выражений компилируется в исполняемый код. И на конец, в этой программе демонстрируется выполнение скомпилированного кода. // Пример простого дерева выражений. using System; using System.Linq; using System.Linq.Expressions; class SimpleExpTree { static void Main { // Представить лямбда-выражение в виде данных. Expression<Func<int, int, bool>> IsFactorExp = (n, d) => (d != 0) ? (n % d) == 0 : false; // Скомпилировать данные выражения в исполняемый код. Func<int, int, bool> IsFactor = IsFactorExp.Compile; // Выполнить выражение. if(IsFactor(10, 5)) Console.WriteLine("Число 5 является множителем 10."); if(!IsFactor (10, 7)) Console.WriteLine("Число 7 не является множителем 10."); Console.WriteLine; } }

Вот к какому результату приводит выполнение этой программы. Число 5 является множителем 10. Число 7 не является множителем 10.

Данный пример программы наглядно показывает два основных этапа применения дерева выражений. Сначала в ней создается дерево выражений с помощью следующе го оператора. Expression<Func<int, int, bool>> IsFactorExp = (n, d) => (d != 0) ? (n % d) == 0 : false;

В этом операторе конструируется представление лямбда-выражения в оперативной памяти. Как пояснялось выше, это представление доступно по ссылке, присваиваемой делегату IsFactorExp. А в следующем операторе данные выражения преобразуются в исполняемый код. Func<int, int, bool> IsFactor = IsFactorExp.Compile;

После выполнения этого оператора делегат IsFactorExp может быть вызван, что бы определить, является ли одно целое число множителем другого.

Обратите также внимание на то, что <Func<int, int, bool> обозначает тип делегата. В этой форме делегата Func указываются два параметра типа int и воз вращаемый тип bool. В рассматриваемой здесь программе использована именно эта форма делегата Func, совместимая с лямбда-выражениями, поскольку для выраже ния требуются два параметра. Для других лямбда-выражений могут подойти иные формы делегата Func в зависимости от количества требуемых параметров. Вообще говоря, конкретная форма делегата Func должна удовлетворять требованиям лямбда- выражения. Методы расширения

  • Читать дальше
  • 1
  • ...
  • 163
  • 164
  • 165
  • 166
  • 167
  • 168
  • 169
  • 170
  • 171
  • 172
  • 173
  • ...

Ебукер (ebooker) – онлайн-библиотека на русском языке. Книги доступны онлайн, без утомительной регистрации. Огромный выбор и удобный дизайн, позволяющий читать без проблем. Добавляйте сайт в закладки! Все произведения загружаются пользователями: если считаете, что ваши авторские права нарушены – используйте форму обратной связи.

Полезные ссылки

  • Моя полка

Контакты

  • chitat.ebooker@gmail.com

Подпишитесь на рассылку: