Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Understand linq syntax [closed]

Tags:

syntax

c#

.net

linq

I am really confused to understand its internal working This is LINQ syntax

string[] test = new test[] { "abc", "", "cd", "", "aa" };
test = test.Where(x => !string.IsNullOrEmpty(x)).ToArray();

I am confused about where syntax how it manages. is it put all array in x? if yes then how it manage x null value?

or

if not then test array values put one by one in the x?

like image 788
user1387147 Avatar asked Jun 01 '12 07:06

user1387147


2 Answers

You should consider the rest of the answers, they are pretty accurate, what I want to show you and maybe this will help you to understand the syntax is that this kind of query can actually be represented in a query syntax like this:

string[] test=new test[]{"abc","","cd","","aa"};

// this is the equivalent to your code
// added explicit type to make it clearer, it's optional
var a = from (string)x in test
        where !string.IsNullOrEmpty(x)
        select x;

if you are familiar with SQL, you will find this syntax easier to read, even when you do not know it, this syntax is cleaner.

When the code is compiled, this query syntax is automatically translated to the C# method syntax, in order to generate the IL, so if you dissasmbly a DLL you will see the method syntax instead of the query syntax

A brief explanation about this code:

  • As you can see an x variable was declared and it's of type string. Why? because your array is an array of strings

  • The in test indicates the source IEnumerable<> to iterate - your array in this case

  • The where is pretty explanatory, it simply selects all not null strings from your array

  • And finally the selects which actually is a projection of the data.

And all this is equivalent to your code

Now you might be asking yourself... When should I use one syntax or the other? Well they are equivalent but the query syntax operators are limited which means that most of the operations are done with method syntax instead of query syntax. What I always do is try to write the code easier to read some code is easier to understand if it is written with a query syntax.

About the method syntax, the x => ... syntax is known as lambda expression, they might look weird if it is the first time you are working with them but you will love them eventually.

Basically lambdas are shortcuts to delegates, so what you are doing with:

x => !string.IsNullOrEmpty(x)

You are creating an anonymous method and the method is being assigned to the delegate parameter. The x represents the string variable.

This topic is really extensive to try to explain it here, but I hope this has given you an idea of what's behind.

Btw you can combine the syntax's like this:

// this is the equivalent to your code
// added explicit type to make it clearer, it's optional
var a = (from (string)x in test
        where !string.IsNullOrEmpty(x)
        select x).ToArray();

If you google LINQ is like googling porm lol the web is plagued with LINQ articles, samples, etc.

A good point of start would be the 101 samples from Microsoft

http://code.msdn.microsoft.com/101-LINQ-Samples-3fb9811b

EDIT

I will try to emulate the Where method so you can have a better example of the lambda expression

// this is basically the declaration of one overload of the Where method
// the this in the parameter declaration, indicates this is an extension method which will be available to all IEnumerable<> objects
// the Func<T, bool> is the interesting part, it is basically a delegate (as a reminder, the last parameter of the Func object indicates the type that must be returned, in this case is a bool)
// the delegate is simply a pointer to a function 
public IEnumerable<T> Where<T>(this IEnumerable<T> source, Func<T, bool> predicate)
{

   ...some logic




   ... yielding back the reuslts
   foreach(var r in res)
   {
      // here is the delegate in action
       if(predicate(r))
           yield return r;
   }
}

As you can see the delegate was called as a function (delegates are pointer to functions) Butt what function??? the one you declared in your code

  • x => !string.IsNullOrEmpty(x) and the x indicates the parameter passed back from the Where method to the external code, where you can inspect it and use it to filter your results

  • The x => is an abbreviation to declare a delegate

  • !string.IsNullOrEmpty(x) this is the body of your anonymous method and as you can see it fulfills the requirements of the Func<T, bool> it is returning a bool (the predicate to filter the elements of the array) and as a parameter, it received the generic T which in this case is a string from your array

Another way to declare the lambda expression is:

test = test.Where(
            (string) x =>
            {
                return !string.IsNullOrEmpty(x)
            })
           .ToArray();

With this syntax is easy to show that they are actually methods (anonymous methods)

like image 140
Jupaol Avatar answered Oct 31 '22 23:10

Jupaol


we can take the statement apart and examine the pieces one at a time

x => !string.IsNullOrEmpty(x) is basically defining a function like the below

bool Filter(string x){
   return !string.IsNullOrEmpty(x)
}

and creates a Predicate based on that function. A predicate is just a delegate - a function you can pass in a variable.

.Where is an extension method that for simplicity could be defined

IEnumerable<T> Where<T>(this IEnumerable<T> sequence,Predicate<T> pred){
   foreach(var elem in sequence){
       if(pred(elem)){
          yield return elem;
       }
   }
}

had you defined the function as Filter is defined above instead of using a lambda your statement would look like this

test = test.Where(Filter).ToArray(); 

so by calling this extension method on your array and passing the above predicate you will iterate over all elements in the array and return all those elements that matches the predicate (Ie. those that are neither null nor have the value of the empty string)

Finally you call the extension method .ToArray() which turns what .Where returned (an IEnumerable<string>) into an array

like image 34
Rune FS Avatar answered Oct 31 '22 23:10

Rune FS