Extension Methods are a new feature in C# 3.0, and they're simply user-made pre-defined functions. An Extension Method enables us to add methods to existing types without creating a new derived type, recompiling, or modifying the original types.
The term 'Lambda expression' has derived its name from 'lambda' calculus which in turn is a mathematical notation applied for defining functions. Lambda expressions as a LINQ equation's executable part translate logic in a way at run time so it can pass on to the data source conveniently.
LINQ introduced the new type called Expression that represents strongly typed lambda expression. It means lambda expression can also be assigned to Expression<TDelegate> type. The . NET compiler converts the lambda expression which is assigned to Expression<TDelegate> into an Expression tree instead of executable code.
LINQ Stands for Language Integrated query which is used to access memory objects, Databases and XML documents and so on. LINQ Stands for Language Integrated query which is used to access memory objects, Databases and XML documents and so on.
For your future reference, all questions of this form are answered by section 7.16 of the C# specification.
Your specific question is answered by this paragraph:
A query expression with a second from
clause followed by a select
clause
from x1 in e1
from x2 in e2
select v
is translated into
( e1 ) . SelectMany( x1 => e2 , ( x1 , x2 ) => v )
So your query:
var query = from a in sequenceA
from b in sequenceB
select ...;
Is the same as
var query = ( sequenceA ) . SelectMany( a => sequenceB , ( a , b ) => ... )
(Note that of course this assumes that the "..." is an expression, and not, say, an expression followed by a query continuation.)
hdv's answer points out that
var query = ( sequenceA ) . SelectMany(
a => ( sequenceB ) . Select( b => ... ) );
would also be a logically valid translation, though it is not the translation we actually perform. In the early days of LINQ implementation, this was the translation we chose. However, as you pile on more from
clauses, it makes the lambdas nest more and more deeply, which then presents the compiler with an enormous problem in type inference. This choice of translation wrecks compiler performance, so we introduced the transparent identifier mechanism to give us a much cheaper way to represent the seamntics of deeply nested scopes.
If these subjects interest you:
For more thoughts on why deeply nested lambdas present a hard problem for the compiler to solve, see:
http://blogs.msdn.com/b/ericlippert/archive/2007/03/26/lambda-expressions-vs-anonymous-methods-part-four.aspx
http://blogs.msdn.com/b/ericlippert/archive/2007/03/28/lambda-expressions-vs-anonymous-methods-part-five.aspx
For more information about transparent identifiers, see this post from Wes Dyer, who implemented them in C# 3.0:
http://blogs.msdn.com/b/wesdyer/archive/2006/12/22/transparent-identifiers.aspx
And my series of articles about them:
http://ericlippert.com/2014/07/31/transparent-identifiers-part-one/
var query = sequenceA.SelectMany(a => sequenceB.Select(b => ...));
Edit: as pointed out by Eric Lippert in the comments, this gives the same results, but is intentionally not how it is translated internally. See his answer for another way to call SelectMany
, which does correspond to the original. Also, added the omitted b =>
for clarity.
Another way to write it would be:
var query = a.Join(b, i => new { }, j => new { }, (i, j) => new { i = i, j = j });
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With