2011-10-14 56 views
4

我通常喜歡的擴展方法,因爲我覺得他們更容易閱讀,但看到由艾爾諾答案this question後,我在想,最小的查詢是什麼樣子,只有擴展方法使用?的LINQ查詢語法和推廣方法

更普遍,在那裏查詢,你可以在一個表格創建而不是其他,或者兩種方法都相同呢?

回答

5

沒有什麼,你可以在其中離不開查詢表達式來進行查詢表達式做 - 查詢表達式只是翻譯成非查詢表達式代碼反正。有很多的查詢,不能在查詢表達式寫成雖然...例如,使用Select過載提供索引以及什麼:

var foo = bar.Select((value, index) => new { value, index }); 

...當然,所有的許多根本不支持查詢表達式的運算符(First等)。

「最小」的查詢將使用SelectMany用於第二from子句,Selectlet條款(引入一個新的透明標識符),Wherewhere子句和Selectselect子句。

0

每個Linq表達式都可以使用擴展方法來表示。無論如何,編譯器都會將Linq翻譯成它們。另一方面,不是每個擴展方法都可以用Linq語法來表示。

1

一些querys只能使用擴展方法的語法(特別是有擴展方法查詢語法不支持)被寫入。擴展方法語法支持查詢語法支持的所有內容,因爲查詢語法被編譯爲完全相同的擴展方法。

另一方面,查詢語法有一些在擴展方法語法(let和某些join)中更加冗長的特性。

join可以通過SelectManyletSelect,介紹一個匿名類型既包括在查詢中的實際變量及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(); 
10

從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.