Для чего используется System.Linq.Expressions в C #? - PullRequest
4 голосов
/ 15 сентября 2009

Является ли LINQ новой функцией в .NET 4.0, не поддерживаемой в старых версиях, таких как .NET 3.5? Для чего это полезно? Похоже, что можно строить деревья выражений. Что такое дерево выражений? Может ли LINQ извлечь информацию, такую ​​как класс, метод и поле, из файла C #?

Может ли кто-нибудь предоставить мне рабочий код, чтобы продемонстрировать, на что способен LINQ?

Ответы [ 7 ]

21 голосов
/ 15 сентября 2009

Linq был добавлен в .Net 3.5 (и добавлен к компилятору c # 3.0, а также в слегка ограниченном виде к компилятору VB.net в том же выпуске)

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

Функциональность Expression - это просто возможность для программы во время выполнения проверять абстрактный синтаксис определенных передаваемых конструкций кода. Они называются лямбдами. И, по сути, это способ более легко писать анонимные функции, в то же время облегчая самоанализ их структуры во время выполнения.

Функциональность 'SQL like', с которой Linq наиболее тесно связан (хотя отнюдь не единственный), называется Linq to Sql, где что-то вроде этого:

from f in Foo where s.Blah == "wibble" select f.Wobble;

компилируется в представление этого запроса, а не просто код для выполнения запроса. Часть, которая делает его linq to sql, является 'backend', который преобразует его в sql. Для этого выражение переводится в операторы SQL Server для выполнения запроса к связанной базе данных с отображением строк в объекты .net и преобразованием логики c # в эквивалентные выражения where. Вы можете применить точно такой же код, если бы Foo представлял собой набор простых объектов .net (в этот момент это «Linq to objects»), тогда преобразование выражения было бы в прямой код .Net.

Лямбда, написанная выше интегрированным языком, на самом деле эквивалентна:

Foo.Where (f => f.Blah == "wibble). Выберите (f => f.Wobble);

Где Foo - это типизированная коллекция. Для баз данных синтезируются классы для представления значений в базе данных, что позволяет как скомпилировать, так и разрешить циклическое переключение значений из областей sql в области .net и наоборот.

Критическим аспектом Language Integrated части Linq является то, что результирующие языковые конструкции являются частями первого класса результирующего кода. Вместо того, чтобы просто вызывать функцию, они обеспечивают способ, которым функция была построена (как выражение), чтобы другие аспекты программы могли манипулировать ею.

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

Многие аспекты того, что делает это возможным, помещены под знаменем "Linq", хотя на самом деле они не являются темами Linq.
Например, анонимные типы требуются для простого использования projection (выбирая подмножество возможных свойств), но анонимные типы могут использоваться и за пределами Linq.

Linq, особенно через лямбды (которые делают написание анонимных делегатов очень легким с точки зрения синтаксиса), привел к расширению функциональных возможностей c #. это подкрепляется методами расширения в IEnumerable<T>, такими как Select (), что соответствует map во многих языках функций, и Where (), соответствующее filter. Подобно анонимным типам, это не само по себе «Linq», хотя многие рассматривают его как очень полезный эффект для развития c # (это не универсальный взгляд, но широко распространенный).

Выражения - более сложная тема, и их понимание совершенно не нужно для использования linq, хотя при их использовании возможны определенные «уловки».В общем, вы бы заботились о выражениях только в том случае, если вы пытались написать провайдеров linq, который представляет собой код для получения выражения, а не просто функцию, и использовать это для выполнения чего-то другого, отличного от того, что делает обычная функция, например для общения с внешним источником данных .

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

4 голосов
/ 15 сентября 2009

Одна из областей этого вопроса, которая еще не была рассмотрена, это деревья выражений. Есть действительно хорошая статья о деревьях выражений (и лямбда-выражениях), доступная здесь .

Еще одна важная вещь, которая возникает в связи с деревьями выражений, заключается в том, что, создавая дерево выражений для определения того, что вы будете делать, вам не нужно на самом деле делать что-либо , Я имею в виду отсроченное исполнение.

//this code will only build the expression tree
var itemsInStock = from item in warehouse.Items
                   where item.Quantity > 0;

// this code will cause the actual execution
Console.WriteLine("Items in stock: {0}", itemsInStock.Count());
1 голос
/ 15 сентября 2009

System.Linq.Expressions предназначен для ручного построения (или машинного генерирования) деревьев выражений. У меня есть ощущение, что, учитывая сложность построения более сложной функциональности, это пространство имен используется недостаточно. Однако это чрезвычайно мощный. Например, один из моих коллег недавно реализовал дерево выражений, которое может автоматически масштабировать любой объект LINQ to SQL, используя функцию накопительной плотности. Каждый столбец получает свое собственное дерево, которое компилируется так быстро. Я создавал специализированный компилятор, который широко использует их для реализации основных функций, а также для склеивания оставшегося кода.

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

1 голос
/ 15 сентября 2009

Это также довольно широко освещено здесь, на SO .

1 голос
/ 15 сентября 2009

LINQ был представлен с .NET 3.5. Этот сайт имеет много примеров.

1 голос
/ 15 сентября 2009

LINQ - это функция .NET 3.5 со встроенной поддержкой языков из C # 3.0 и Visual Basic 2008. Существует множество примеров для MSDN .

0 голосов
/ 15 сентября 2009

Вот много примеров Linq:
http://msdn.microsoft.com/en-us/vcsharp/aa336746.aspx

...