Как 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; } } }
используйте соответствующие точки останова.