繁体   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