[英]Linq query syntax and extension methods
我通常更喜歡擴展方法,因為他們發現它們更容易閱讀,但在看到Erno對這個問題的答案后,我想知道最小查詢看起來如何只使用擴展方法?
更一般地說,是否存在可以在一種形式而不是另一種形式中創建的查詢,或者兩種方法是否相同?
來自ILSpy:
這個
var minimum = (from p1 in differenceList
from p2 in differenceList
let distance = Math.Abs(p1.X - p2.X)
where !object.ReferenceEquals(p1, p2)
orderby distance
select new { Point1 = p1, Point2 = p2, Distance = distance }).First();
是(有點清潔)和評論
var minimum = differenceList
// The two from
.SelectMany(
p1 => differenceList,
(p1, p2) =>
new {
p1 = p1,
p2 = p2
})
// The let
.Select(q =>
new{
q = q,
distance = Math.Abs(q.p1.X - q.p2.X)
})
// The where
.Where(r => !object.ReferenceEquals(r.q.p1, r.q.p2))
// The orderby
.OrderBy(r => r.distance)
// The final select
.Select(r => new
{
Point1 = r.q.p1,
Point2 = r.q.p2,
Distance = r.distance
})
// The First
.First();
我必須說實話,我唯一不知道怎么做“手工”的是兩個from
。 我懷疑它是一個SelectMany
,但它至少需要30分鍾來破解它。 如果您有興趣,請在ILSpy Options->Decompiler and deactivate "Decompile query expressions.
在查詢表達式中沒有什么可以做的,沒有查詢表達式就無法完成 - 無論如何,查詢表達式只是被翻譯成非查詢表達式代碼。 有很多查詢無法在查詢表達式中編寫,但是...例如,使用Select
過載的任何東西都提供了索引:
var foo = bar.Select((value, index) => new { value, index });
...當然,所有許多運算符根本不受查詢表達式的支持( First
etc)。
“最小”查詢將使用SelectMany
用於第二個from
子句, Select
用於let
子句(引入新的透明標識符), Where
用於where
子句, Select
用於select
子句。
某些查詢只能使用擴展方法語法編寫(特別是查詢語法不支持的擴展方法)。 擴展方法語法支持查詢語法支持的所有內容,因為查詢語法被編譯為完全相同的擴展方法。
另一方面,查詢語法具有一些在擴展方法語法( let
和某些join
s)中更加冗長的特性。
join
可以被替換SelectMany
,並let
一個Select
是引入了一個匿名類型既包括在查詢中的實際變量和介紹的變量let
條款。
擴展方法語法中的干凈版本如下所示:
differenceList
.SelectMany(p1=>differencelist,(p1,p2) => new {Point1 = p1,Point2 = p2,
Distance=Math.Abs(q.p1.X - q.p2.X)})
.Where(e=>!object.ReferenceEquals(e.p1,e.p2))
.OrderBy(e=>e.Distance)
.First();
每個Linq表達式都可以使用擴展方法表示。 無論如何,編譯器將Linq轉換為它們。 另一方面,並非每種擴展方法都可以用Linq語法表示。
聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.