![](/img/trans.png)
[英]If I have a function that returns AsEnumerable, does it cache all result?
[英]Does AsEnumerable() cache all result (LINQ)
當我們在序列上調用查詢運算符時,將調用特定於序列的運算符。
我的意思是,如果我在IEnumerable<>
上調用Where<>()
運算符,將在Enumerable類中定義將被調用的運算符,如果在IQueryable<>
對其進行調用,則將調用Queryable類中定義的那個運算符。
考慮在Enumerable類中定義的Reverse運算符。
如果我想在Iqueryable<>
上調用它,則必須使用AsEnumerable<>()
運算符首先將其轉換為IEnumerable<>
。
db.Countries.OrderBy(cntry=>cntry.CountryName).AsEnumerable().Reverse()
但是Reverse運算符必須同時擁有所有記錄,以便可以將它們反轉。
在上面的代碼中,是否所有記錄都首先加載到內存中,然后Reverse()運算符將其反轉?
AsEnumerable
除了更改表達式的編譯時類型外,什么也不做。
它是這樣實現的:
public static IEnumerable<T> AsEnumerable<T>(this IEnumerable<T> source)
{
return source;
}
它甚至不檢查無效性!
唯一的一點是更改編譯時類型,以強制使用Enumerable擴展方法而不是Queryable來執行其余的查詢。 這就像強制轉換-除了強制強制轉換在查詢過程中通常很不方便外,對於匿名類型,無論如何您都無法強制轉換。
因此,它實際上是關於查詢的“源”在枚舉時的作用。 在返回任何結果之前,該源代碼是否將所有內容都加載到內存中? IIRC,LINQ to SQL實際上會將所有內容加載到內存中-但我可能是錯的。 當然, Reverse
無論如何都會緩沖任何東西,但這並不意味着它將使用雙倍的內存-在大多數情況下,這僅意味着它將緩沖對對象的引用 。 它不會為每個對象創建一個新副本。
IQueryable<T>
擴展了IEnumerable<T>
,因此AsEnumerable是冗余的。 但是,如果使用它,AsEnumerable將不會貪婪地加載集合(那將是一個非常煩人的“功能”)。 顯然,反向將需要整個過程。 Mono使用List<T>
和一個簡單的迭代器生成器實現Enumerable.Reverse ,反向生成。
我相信AsEnumerable的唯一真正目的是強制使用IEnumerable顯式接口實現。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.