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?
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:
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
. I suspected it was a SelectMany
, but it would have taken me at least 30 minutes to crack it. If you are interested, in 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:
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).
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.
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).
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.
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. The compiler translates Linq into them anyway. On the other hand, not every extension method can be expressed in Linq syntax.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.