[英]I need help understanding LINQ. Where is my understanding going wrong?
我會盡力讓您理解它,並且讓我知道我要去哪里了。
為了簡單起見,讓我們假設我們生活在一個只有
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);
}
我首先了解的是查詢本身不會創建Ienumerable<int>
; 它創建與查詢關聯的表達式樹 。 查詢所返回的元件yield
在由編譯器創建的一個不可見的功能編等
public static IEnumerable<int> MyInvisibleFunction ( List<int> Source )
{
foreach ( int i in Source.Reverse() )
{
if ( i % 2 == 1 )
{
yield return i;
}
}
}
(當然,這是一個奇怪的示例,因為Source.Reverse()
本身是一個查詢,但是無論如何...)
現在我很困惑表達發辮在這里發揮作用的地方。 當我想到表達樹時,我想到了像
(3 % 1 > 0)
/ \
/ \
(3 % 1) > 0
/ \
3 % 1
在我創造的小世界中。 但是在我的LINQ查詢中,像這樣的樹在哪里起作用?
from i in All
where i % 2 == 1
orderby i descending
select i
??? 那是我不明白的。 我正在查看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);
讓我們分解一下。 首先,編譯器將其轉換為
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);
接下來,編譯器執行重載解析並評估擴展方法
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);
接下來的lambda被刪除了:
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);
實際上,lambda的精確去除並不是這樣。 它們也會被緩存,但是讓我們忽略這個細節。
我認為您不希望將foreach廢止。 有關詳細信息,請參見C#規范。
如果您想知道Where和OrderBy的功能,請閱讀源代碼。
表達式樹不會在您的查詢中起作用,因為您的源是常規的內存列表。 –西奧多羅斯·查茲吉安娜基斯
這是真的。
沒有生成不可見的迭代器函數。 您的查詢翻譯為:
List<int> All = new List<int> { 1, 2, 3, 4, 5 };
IEnumerable<int> Filtered =
All
.Where(i => i % 2 == 0)
.OrderByDescending(i => i);
不需要自定義迭代器。 該語言僅調用現有的庫函數。
對於IQueryable
,這是相同的,只是不將lambda參數作為委托而是作為表達式樹傳遞。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.