Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Differences in LINQ vs Method expression

Tags:

c#

linq

Why the Linq expression IL results in omission of the Select projection whereas the corresponding method expression keeps the Select projection ?

I suppose these two pieces of code does the same.

 var a = from c in companies
                where c.Length >10
                select c;

//

var b = companies.Where(c => c.Length > 10).Select(c => c);

//IL - LINQ

IEnumerable<string> a = this.companies.
Where<string>(CS$<>9__CachedAnonymousMethodDelegate1);

//IL

   IEnumerable<string> b = this.companies.Where<string>
   (CS$<>9__CachedAnonymousMethodDelegate4).Select<string, string>
   (CS$<>9__CachedAnonymousMethodDelegate5);

Then why the difference in IL?

EDITED : then why

  var a = from c in companies
           select c;

result in SELECT projection even inside IL. it can also be omitted right ?

like image 202
Ashley John Avatar asked Sep 29 '11 05:09

Ashley John


People also ask

What is difference between LINQ and lambda expression?

Language Integrated Query (LINQ) is feature of Visual Studio that gives you the capabilities yo query on the language syntax of C#, so you will get SQL kind of queries. And Lambda expression is an anonymous function and is more of a like delegate type.

What is the difference between query syntax and method syntax in LINQ?

Query syntax and method syntax are semantically identical, but many people find query syntax simpler and easier to read. Some queries must be expressed as method calls. For example, you must use a method call to express a query that retrieves the number of elements that match a specified condition.

What are the different LINQ query methods?

LINQ has three ways to write the queries:Using Query Syntax. Using Method Syntax. Using Mixed Syntax.

What is expression in LINQ?

In LINQ, a query expression is compiled to expression trees or to delegates, depending on the type that is applied to query result. The IEnumerable<T> type LINQ queries are compiled to delegates and IQueryable or IQueryable<T> queries are compiled to expression trees.


2 Answers

The C# compiler is clever and remove useless statement from Linq. Select c is useless so the compiler remove it. When you write Select(c=>c) the compiler can't say that's the instruction is useless because it' a function call and so it doesn't remove it. If you remove it yourself IL become the same.

EDIT : Linq is a "descriptive" language : you say what you want and the compiler transforms it well. You don't have any control on that transformation. The compiler try to optimize function call and don't use Select because you don't do projection so it's useless. When you write Select(c => c) you call a function explicitely so the compiler won't remove it.

var a = from c in companies select c;
var a = c.Select(elt=>elt);

Select is usefull in this example. If you remove it a has the type of c; otherwise a is an IEnumerable

like image 156
meziantou Avatar answered Oct 05 '22 06:10

meziantou


@mexianto is of course correct that this is a compiler optimization.

Note that this is explicitly called out in the language specification under "Degenerate Query expressions." Also note that the compiler is smart enough to not perform the optimization when doing so would return the original source object (the user might want to use a degenerate query to make it difficult for the client to mutate the source object, assuming that it is mutable).

7.16.2.3 Degenerate query expressions

A query expression of the form

from x in e select x

is translated into

( e ) . Select ( x => x ) 

[...] A degenerate query expression is one that trivially selects the elements of the source. A later phase of the translation removes degenerate queries introduced by other translation steps by replacing them with their source. It is important however to ensure that the result of a query expression is never the source object itself, as that would reveal the type and identity of the source to the client of the query. Therefore this step protects degenerate queries written directly in source code by explicitly calling Select on the source. It is then up to the implementers of Select and other query operators to ensure that these methods never return the source object itself.

like image 32
Ani Avatar answered Oct 05 '22 05:10

Ani