簡體   English   中英

Linq查詢語法和擴展方法

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM