Linq查询语法和扩展方法

4

我通常喜欢使用扩展方法,因为我认为它们更易于阅读,但在看到Erno对这个问题的回答后,我想知道仅使用扩展方法的最小查询会是什么样子?

更一般地说,有没有一种形式可以创建查询而另一种形式却不行,还是两种方法都是等效的?

4个回答

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中选择选项->反编译器并取消勾选“反编译查询表达式”。


6

在没有查询表达式的情况下,您可以做到的事情,在有查询表达式的情况下也同样可以做到 - 查询表达式只是被翻译成非查询表达式的代码而已。然而,有很多查询无法使用查询表达式编写...例如,任何使用Select重载函数并同时提供索引的情况:

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

当然,还有许多运算符在查询表达式中根本不支持(如First等)。

最基本的查询将使用SelectMany作为第二个from子句,Select作为let子句(引入新的透明标识符),Where作为where子句,以及Select作为select子句。


1

有些查询只能使用扩展方法语法编写(特别是一些查询语法不支持的扩展方法)。扩展方法语法支持查询语法支持的所有功能,因为查询语法被编译成完全相同的扩展方法。

另一方面,查询语法具有一些在扩展方法语法中更加冗长的特性(例如let和某些join)。

join可以用SelectMany替换,而let则可以用一个Select来代替,该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();

0
每个Linq表达式都可以使用扩展方法来表示。编译器无论如何都会将Linq翻译成它们。另一方面,并不是每个扩展方法都可以用Linq语法来表示。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接