How LINQ works internally?
我喜欢在.NET上使用Linq,但我想知道它在内部是如何工作的?
有人知道吗?
THKS。
询问LINQ的一个特定方面更有意义。这有点像问"Windows是如何工作"的。
从C的角度来看,Linq的关键部分是对我而言的:
- 表达式树。这些是代码作为数据的表示。例如,表达式树可以表示"接受一个字符串参数,对其调用length属性,并返回结果"的概念。事实上,这些作为数据而不是编译代码存在意味着LINQ提供者(如LINQ to SQL)可以分析它们并将它们转换为SQL。
lambda表达式。这些表达式如下:
1
2
3x => x * 2
(int x, int y) => x * y
() => { Console.WriteLine("Block"); Console.WriteLine("Lambda"); }lambda表达式被转换为委托树或表达式树。
匿名类型。这些表达式如下:
1new { X=10, Y=20 }。
这些仍然是静态类型的,只是编译器用属性
X 和Y 为您生成了一个不可变的类型。这些通常与var 一起使用,它允许从初始化表达式推断局部变量的类型。查询表达式。这些表达式如下:
1
2
3from person in people
where person.Age < 18
select person.Name这些代码由C编译器翻译成"普通"的C.0(即不使用查询表达式的表单)。然后应用重载解决方案等,这对于能够在多个数据类型中使用相同的查询语法是绝对关键的,而不需要编译器了解诸如query able之类的类型。上述表达式将转换为:
1
2people.Where(person => person.Age < 18)
.Select(person => person.Name)。
扩展方法。这些是静态方法,可以将其用作第一个参数类型的实例方法。例如,这样的扩展方法:
1
2
3
4public static int CountAsciiDigits(this string text)
{
return text.Count(letter => letter >= '0' && letter <= '9');
}。
然后可以这样使用:
1
2string foo ="123abc456";
int count = foo.CountAsciiDigits();注意,
CountAsciiDigits 的实现使用了另一种扩展方法,Enumerable.Count() 。- 局部变量类型推理
- 自动属性(未在VB 9.0中实现)
- 扩展方法
- lambda表达式
- 匿名类型初始值设定项
- 查询理解
小精灵
这是大多数相关的语言方面。然后是标准查询运算符的实现,在Linq提供程序中,如Linq to Objects和Linq to SQL等。我有一个关于如何实现Linq to Objects相当简单的演示—它位于C深入网站的"Talks"页面上。
像linq to sql这样的提供者通常是通过
这包括你所感兴趣的一切吗?如果你还有什么特别想知道的,编辑一下你的问题,我就去试试。
LINQ基本上是C 3.0离散特性的组合:
小精灵
有关到那里的旅程(Linq)的更多信息,请参见2008年Langnet上Anders的视频:
http://download.microsoft.com/download/c/e/5/ce5434ca-4f54-42b1-81ea-7f5a72f3b1dd/1-01%20-%20csharp3%20-%20anders%20hejlsberg.wmv
在简单的表单中,编译器接受代码查询,并将其转换为一组通用类和调用。在下面,对于linq2sql,使用dbcommand、dbdatareader等构造和执行动态SQL查询。
假设你有:
1 | var q = from x in dc.mytable select x; |
它被转换成以下代码:
1 2 3 4 5 6 7 | 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在实际中给出了一个很好的解释。
我有一个小的C程序,演示了C中LINQ的实现。
1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 | 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; } } } |
。
使用适当的断点。