我会尽力帮助你理解它,你让我知道我哪里出错了.
为简单起见,我们假设我们生活在一个只有的词中
1,2,3,4,5%,>他们通常的预防我想解释当我这样做时会发生什么
List<int> All = new List<int> { 1, 2, 3, 4, 5 };
IEnumerable<int> Filtered = from i in All
where i % 2 == 1
orderby i descending
select i;
foreach ( var i in Filtererd )
{
Console.WriteLine(i);
}
Run Code Online (Sandbox Code Playgroud)
我首先理解的是查询本身并没有创建Ienumerable<int>; 它创建与查询关联的表达式树.查询返回的元素yield在编译器创建的不可见函数中编辑
public static IEnumerable<int> MyInvisibleFunction ( List<int> Source )
{
foreach ( int i in Source.Reverse() )
{
if ( i % 2 == 1 )
{
yield return i;
}
}
}
Run Code Online (Sandbox Code Playgroud)
(当然这是一个奇怪的例子,因为Source.Reverse()它本身就是一个查询,但无论如何...)
现在我很困惑表达发辫在这里发挥作用.当我想到表达树时,我会想到树木
(3 % 1 > 0)
/ \
/ \
(3 % 1) > 0
/ \
3 % 1
Run Code Online (Sandbox Code Playgroud)
在我创造的小世界里.但是,在我的LINQ查询中,这样的树会在哪里播放
from i in All
where i % 2 == 1
orderby i descending
select i
Run Code Online (Sandbox Code Playgroud)
??? 这就是我不明白的地方.我正在查看Expression类,我看到它如何创建我展示的示例树,但我看不出它会在我的查询中发挥作用.
我会尽力帮助你理解它,你让我知道我哪里出错了.
好.
我首先理解的是查询本身并没有创建
Ienumerable<int>;
这句话完全错了.
它创建与查询关联的表达式树.
这句话也完全错了.
查询返回的元素在编译器创建的不可见函数中生成
这句话也完全错了.
这样的树在我的LINQ查询中的位置
它没有.您的查询不使用表达式树.
我正在看Expression类,我看到它如何创建我展示的示例树,但我看不出它会在哪里发挥作用
它没有.
想要掩饰我做的事情
List<int> All = new List<int> { 1, 2, 3, 4, 5 };
IEnumerable<int> Filtered = from i in All
where i % 2 == 1
orderby i descending
select i;
foreach ( var i in Filtererd )
Console.WriteLine(i);
Run Code Online (Sandbox Code Playgroud)
让我们分解吧.首先,编译器将其转换为
List<int> All = new List<int> { 1, 2, 3, 4, 5 };
IEnumerable<int> Filtered = All.Where(i => i % 2 == 1).OrderBy(i => i);
foreach ( var i in Filtererd )
Console.WriteLine(i);
Run Code Online (Sandbox Code Playgroud)
接下来,编译器会执行重载决策并评估扩展方法
List<int> All = new List<int> { 1, 2, 3, 4, 5 };
IEnumerable<int> Filtered =
Enumerable.OrderBy<int>(
Enumerable.Where<int>(All, i => i % 2 == 1)),
i => i));
foreach ( var i in Filtererd )
Console.WriteLine(i);
Run Code Online (Sandbox Code Playgroud)
下一个lambdas是desugared:
static bool A1(int i) { return i % 2 == 1; )
static int A2(int i) { return i }
...
List<int> All = new List<int> { 1, 2, 3, 4, 5 };
IEnumerable<int> Filtered =
Enumerable.OrderBy<int>(
Enumerable.Where<int>(All, new Func<int, bool>(A1))),
new Func<int, int>(A2)));
foreach (var i in Filtererd )
Console.WriteLine(i);
Run Code Online (Sandbox Code Playgroud)
这实际上并不是羔羊如何完全被贬低; 它们也被缓存,但让我们忽略这个细节.
我假设你不希望foreach脱毒.有关详细信息,请参阅C#规范.
如果您想知道Where和OrderBy的作用,请阅读源代码.
| 归档时间: |
|
| 查看次数: |
321 次 |
| 最近记录: |