我喜欢在.net上使用LINQ,但我想知道它在内部是如何工作的?
有谁知道吗?
THKS。
答案 0 :(得分:79)
询问LINQ的特定方面更有意义。这有点像问“如何运作Windows”。
从C#的角度来看,LINQ的关键部分对我来说是
Lambda表达式。这些是这样的表达式:
x => x * 2
(int x, int y) => x * y
() => { Console.WriteLine("Block"); Console.WriteLine("Lambda"); }
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 to Objects的相当简单的演示文稿 - 它位于"Talks"页面上深度网站上的C#。
LINQ to SQL等提供程序的工作方式通常是通过Queryable
类。他们的核心是将表达式树转换为其他查询格式,然后使用执行这些进程外查询的结果构造适当的对象。
这涵盖了您感兴趣的一切吗?如果有什么特别的东西你仍然想知道,只需编辑你的问题,我就可以去了。
答案 1 :(得分:5)
LINQ基本上是这些C#3.0离散功能的组合:
有关到达目的地的更多信息(LINQ),请参阅LANGNET 2008中Anders的视频:
答案 2 :(得分:4)
在简单的表单中,编译器会将您的代码查询转换为一堆泛型类和调用。在下面,在Linq2Sql的情况下,使用DbCommand,DbDataReader等构造和执行动态SQL查询。
说你有:
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 }
)
);
许多泛型,巨大的开销。
答案 3 :(得分:1)
基本上,linq是一些语言工具(编译器)和一些框架扩展的混合体。因此,当您编写linq查询时,它们将使用适当的接口(如IQuerable)执行。另请注意,运行时在linq中没有任何作用。
但在简短的回答中很难对linq公正。我建议你读一些书来吸引自己。我不确定这本告诉你Linq内部的书,但Linq in Action给了你很好的帮助。
答案 4 :(得分:0)
我有一个小的C#程序,演示了在C#中实现LINQ。
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;
}
}
}
使用适当的断点。