Как LINQ работает внутренне?
Я люблю использовать LINQ на .net, но мне интересно знать, как это работает внутри?
кто-нибудь знает что?
Thks.
5 ответов:
имеет смысл спросить о конкретном аспекте LINQ. Это немного похоже на вопрос "как работает Windows" в противном случае.
ключевые части LINQ для меня, с точки зрения C#:
- выражение деревьев. Это представления кода как данных. Например, дерево выражений может представлять понятие "взять строковый параметр, вызвать свойство Length на нем и вернуть результат". Дело в том, что они существуют как сведения а чем как скомпилированный код означает, что поставщики LINQ, такие как LINQ to SQL, могут анализировать их и преобразовывать в SQL.
лямбда-выражения. Вот такие выражения:
x => x * 2 (int x, int y) => x * y () => { Console.WriteLine("Block"); Console.WriteLine("Lambda"); }лямбда-выражения преобразуются либо в представители или выражение деревьев.
анонимные типы. Вот такие выражения:
new { X=10, Y=20 }они все еще статически типизированы, это просто компилятор создает для вас неизменяемый тип со свойствами
XиY. Они обычно используются сvarчто позволяет вывести тип локальной переменной из ее выражения инициализации.выражения запросов. Вот такие выражения:
from person in people where person.Age < 18 select person.Nameони переводятся компилятором C# в "нормальный" C# 3.0 (т. е. форма, которая не использует выражения запроса). Разрешение перегрузки и т. д. применяется впоследствии, который это абсолютно ключ к возможности использовать один и тот же синтаксис запроса с несколькими типами данных, без компилятора, имеющего какие-либо знания о типах, таких как Queryable. Приведенное выше выражение будет переведено на:
people.Where(person => person.Age < 18) .Select(person => person.Name)методы расширения. Это статические методы, которые можно использовать так, как если бы они были методами экземпляра типа первого параметра. Например, такой метод расширения:
public static int CountAsciiDigits(this string text) { return text.Count(letter => letter >= '0' && letter <= '9'); }затем можно использовать как это:
string foo = "123abc456"; int count = foo.CountAsciiDigits();обратите внимание, что реализация
CountAsciiDigitsиспользует другой метод расширения,Enumerable.Count().это самое актуальное язык аспекты. Затем существуют реализации стандартных операторов запросов в поставщиках LINQ, таких как LINQ to Objects и LINQ to SQL и т. д. У меня есть презентация о том, как достаточно просто реализовать LINQ для объектов - это на "переговоры" страница C# в глубину вебсайт.
способ работы таких поставщиков, как LINQ to SQL, обычно осуществляется через
Queryableкласса. По своей сути, они переводят деревья выражений в другие форматы запросов, а затем построить соответствующие объекты с результаты выполнения этих запросов.это охватывает все, что вас интересовало? Если есть что-то конкретное, о чем вы все еще хотите знать, просто отредактируйте свой вопрос, и я пойду.
LINQ-это в основном комбинация дискретных функций C# 3.0 из них:
- вывод типа локальной переменной
- автоматические свойства (не реализовано в VB 9.0)
- методы расширения
- лямбда-выражения
- анонимный инициализаторы типа
- понимание запросов
для получения дополнительной информации о путешествии, чтобы добраться туда (LINQ), смотрите это видео Андерса в LANGNET 2008:
в простой форме, компилятор принимает код-запрос и преобразует его в кучу универсальных классов и вызовов. Ниже, в случае Linq2Sql, динамический SQL-запрос строится и выполняется с использованием DbCommand, DbDataReader и т. д.
скажем, у вас есть:
var q = from x in dc.mytable select x;преобразуется в следующий код:
IQueryable<tbl_dir_office> q = dc.mytable.Select<tbl_dir_office, tbl_dir_office>( Expression.Lambda<Func<mytable, mytable>>( exp = Expression.Parameter(typeof(mytable), "x"), new ParameterExpression[] { exp } ) );много дженериков, огромные накладные расходы.
в основном linq представляет собой смесь некоторых языковых средств (компилятор) и некоторых расширений фреймворка. Поэтому, когда вы пишете запросы linq, они выполняются с использованием соответствующих интерфейсов, таких как IQuerable. Также обратите внимание, что среда выполнения не имеет роли в linq.
но трудно отдать должное linq в коротком ответе. Я рекомендую вам прочитать какую-нибудь книгу, чтобы попасть в нее. Я не уверен в книге, которая рассказывает вам внутренности Linq, но Linq в действии дает хороший работы об этом.
У меня есть небольшая программа на C#, которая демонстрирует реализацию LINQ в C#.
class Program { static void Main(string[] args) { //Eventhough we call the method here, it gets called ONLY when the for loop is executed var Cities = LinQFunction(new List<string>() { "Bangalore", "Mysore", "Coorg", "Tumkur", "Kerala", "TamilNadu" }); //LinQFunction() gets callled now foreach(var city in Cities) { Console.WriteLine(city); } } //This function is called ONLY when the foreach loop iterates and gets the item from the collection static IEnumerable<string> LinQFunction(List<string> cities) { foreach (var item in cities) { //Return each 'item' at a time yield return item; } } }используйте соответствующие точки останова.