[英]Linq query syntax and extension methods
I usually prefer the extension methods, because they i find them easier to read, but after seeing the answer by Erno to this question I was wondering how the minimum query would look with only extension methods used? 我通常更喜欢扩展方法,因为他们发现它们更容易阅读,但在看到Erno对这个问题的答案后,我想知道最小查询看起来如何只使用扩展方法?
And more generally, are there queries that you can create in one form but not the other, or are both approaches equivalent? 更一般地说,是否存在可以在一种形式而不是另一种形式中创建的查询,或者两种方法是否相同?
Taken from ILSpy: 来自ILSpy:
This 这个
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();
is (with a little cleaning) and with comments 是(有点清洁)和评论
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();
I have to tell the truth, the only thing I didn't know how to do "by hand" was the two from
. 我必须说实话,我唯一不知道怎么做“手工”的是两个
from
。 I suspected it was a SelectMany
, but it would have taken me at least 30 minutes to crack it. 我怀疑它是一个
SelectMany
,但它至少需要30分钟来破解它。 If you are interested, in ILSpy Options->Decompiler and deactivate "Decompile query expressions.
如果您有兴趣,请在ILSpy
Options->Decompiler and deactivate "Decompile query expressions.
There's nothing you can do in query expressions which can't be done without query expressions - query expressions are just translated into non-query-expression code anyway. 在查询表达式中没有什么可以做的,没有查询表达式就无法完成 - 无论如何,查询表达式只是被翻译成非查询表达式代码。 There are plenty of queries that can't be written in query expressions though... for example, anything using the
Select
overload which provides the index as well: 有很多查询无法在查询表达式中编写,但是...例如,使用
Select
过载的任何东西都提供了索引:
var foo = bar.Select((value, index) => new { value, index });
... and of course, all the many operators which aren't supported by query expressions at all ( First
etc). ...当然,所有许多运算符根本不受查询表达式的支持(
First
etc)。
The "minimum" query would use SelectMany
for the second from
clause, Select
for the let
clause (introducing a new transparent identifier), Where
for the where
clause, and Select
for the select
clause. “最小”查询将使用
SelectMany
用于第二个from
子句, Select
用于let
子句(引入新的透明标识符), Where
用于where
子句, Select
用于select
子句。
Some querys can only be written using the extension method syntax(in particular there are extension methods the query syntax doesn't support). 某些查询只能使用扩展方法语法编写(特别是查询语法不支持的扩展方法)。 The extension method syntax supports everything the query syntax supports, since the query syntax gets compiled into the very same extension methods.
扩展方法语法支持查询语法支持的所有内容,因为查询语法被编译为完全相同的扩展方法。
On the other hand the query syntax has a few features which are a bit more verbose in the extension method syntax ( let
and certain join
s). 另一方面,查询语法具有一些在扩展方法语法(
let
和某些join
s)中更加冗长的特性。
join
can be replaced by SelectMany
and let
with a Select
that introduces a anonymous type that includes both the actual variable in the query and the variable introduced in the let
clause. join
可以被替换SelectMany
,并let
一个Select
是引入了一个匿名类型既包括在查询中的实际变量和介绍的变量let
条款。
A clean version in extension method syntax would look like this: 扩展方法语法中的干净版本如下所示:
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();
Every Linq expression can be expressed using extension methods. 每个Linq表达式都可以使用扩展方法表示。 The compiler translates Linq into them anyway.
无论如何,编译器将Linq转换为它们。 On the other hand, not every extension method can be expressed in Linq syntax.
另一方面,并非每种扩展方法都可以用Linq语法表示。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.