12,698,686 members (27,119 online)
alternative version

65.3K views
114 bookmarked
Posted

# Demystify LINQ in 10 Minutes

, 23 Jun 2014 CPOL
 Rate this:
Journey of C# up to LINQ in less than 10/15 minutes

## Introduction

A lot of good articles are doing a great job of explaining LINQ. From syntax to concept and projects, LINQ is well covered. The aim of this article is not to repeat / recycle this material into one big blob. Check out the list of good books for details. My favorite is this little pocket reference.

We will need some scaffolding code. We will use a `City `class as follows:

```class City
{
private string _name;
private string _state;

public City(string name, string state)
{
this._name = name;
this._state = state;
}

public string Name
{
get
{
return _name;
}
}

public string State
{
get
{
return _state;
}
}
}```

Let’s create a collection of cities and then iterate over this collection using `foreach `as shown below:

```List<City> cities = new List<City>();
City c = new City("Santa Ana", "CA");
City c1 = new City("Irvine", "CA");
City c2 = new City("Bloomington", "IN");

foreach (City tempCity in cities)
{
Console.WriteLine("City Name : {0} and State : {1}",tempCity.Name, tempCity.State);
}```

Let’s filter this collection based on some criteria. Say we want cities from California only. A very simple solution will be to add an `if` condition inside the `foreach `loop as shown below:

```if (tempCity.State == "CA")
Console.WriteLine("City Name : {0} and State : {1}", tempCity.Name, tempCity.State);
```

This is a good enough solution. The problem with this code is “tight coupling”. C# 1.0 provided a delegate based composable solution to this problem. The following is the refactored version of this code:

#### Step 1

`delegate bool IsParticularState(City c);`

#### Step 2

```static bool IsCalifornia(City c)
{
return c.State == "CA" ? true : false;
}```

#### Step 3

`PrintCityInfo(cities, new IsParticularState(IsCalifornia));`

#### Step 4

```static void PrintCityInfo(List<city> _cities, IsParticularState filter)
{
foreach (City localCity in _cities)
{
if (filter(localCity))
{
Console.WriteLine("City Name : {0} and State : {1}",
localCity.Name, localCity.State);
}
}
}</city>```

As shown in step 1, we added a `delegate IsParticularState`. Step 2 is the target method for this `delegate`. Step 3 is the refactored call to the `foreach `loop which takes a `delegate `and `cities `collection as an input parameter. Step 4 will output the `city name `and `state`.

Notice the filter instead of the simple `if `condition. `filter(localCity)` is a `delegate `call. By doing this, we decoupled the filter logic into a separate method:

`static bool IsCalifornia(City c)`

Still this is too much of a code for implementing a simple filter logic. Wouldn't it be nice if we don't have to add an additional filter method. Yes, that's where C# 2.0 anonymous methods will be helpful. So, the code above can be refactored as follows:

`PrintCityInfo(cities,delegate(City ctemp){return (ctemp.State == "CA"?true:false);});`

Notice the inline `delegate `and anonymous method. This is a C# 2.0 feature - anonymous because this method has no name.

This is a good move, but still needs a `delegate `code. What if we want to improve this code using C# 3.0. Instead of using anonymous methods, we can use lambda expression as follows:

`PrintCityInfo(cities,ctemp=>ctemp.State=="CA");`

Isn't this code elegant? From 7+ lines, a `delegate `and a target method call in C# 1.0 to less than half a line of code in C# 3.0. This is the power of lambda expression. Underneath, the compiler is doing all the heavy lifting for us. Lambda expression is a combination of implicit variable and anonymous methods. In our example, `ctemp `is an implicit variable and `ctemp.State=="CA"` is an anonymous method.

And now comes LINQ. What if we want to filter the end result on multiple conditions or want to sort the output based on some predefined order like `city name`? We can do this without LINQ. But LINQ provides an elegant solution for this as shown below:

```PrintCityInfousingLINQ(from ctemp in cities
where ctemp.State=="CA"
select ctemp);

static void PrintCityInfousingLINQ(IEnumerable<city> _cities)
{
foreach (City localCity in _cities)
{

Console.WriteLine("City Name : {0} and State : {1}",
localCity.Name, localCity.State);

}
}</city>```

Here we defined a new method `PrintCityInfousingLINQ`. This is the same as the `PrintCityInfo `method. Rather than taking a collection and `delegate `as an input parameter, `PrintCityInfousingLINQ `takes enumerator as an input parameter. Another important factor is generics. Generics add the type safety and provide all other well documented benefits.

Let's order the end result by `city name`. This is a typical `order by clause `in TSQL. With LINQ, this can be written as follows:

```PrintCityInfousingLINQ(from ctemp in cities
where ctemp.State=="CA"
orderby ctemp.Name
select ctemp);```

Without the `orderby `clause, Santa Ana will be the first result. With `order by `clause, Irvine will be the first record.

### Conclusion

From the trivial `if `condition in C# 1.0 to LINQ in C# 3.0, there is a continuum of logic and syntax. Imagine writing...

```from ctemp in cities
where ctemp.State=="CA"
orderby ctemp.Name
select ctemp;```

... using `if `conditions or `delegate`s. LINQ brings the much needed improvement on the syntax front in addition to its support for SQL, XML and objects. With LINQ, intent is closely matched with the language syntax.

At a midnight debate by the empty parking lot of a grad school, someone said something to the effect of –“power of any programming language is its ability to say very complex things very easily. Like The woods are lovely, dark, and deep, But I have promises to keep…

LINQ is one more step in the right direction. What do you think?

Update :  While explaning LINQ to folks coming in from traditional procedural programming background, I used this example to explain Lambda basics. Hope this will be useful to others - please let me know - LINQPad is used to test this code

```delegate bool diseven(int i);

void Main(){
int[] mi = new int[]{2,3,4,5,1};
"Count Even Numbers".Dump();
diseven di =isEven;
int counter=0;
foreach(int i in mi)
if(di(i))
counter++;
mi.Count(delegate(int i){
return i%2==0;
}).Dump("Using delegate");
Func<int,bool> fm = i =>i%2==0;
mi.Count(i=>fm(i)).Dump("using built in delegate Func");
mi.Count(i=>i%2==0).Dump("using Lambda");
}

bool isEven(int i)
{
return i%2==0;
}```

## History

• 26th June, 2008: Initial post
• 22 June,2014 : Included Lambda example

## About the Author

 Architect Wells Fargo United States
MS Computer Science + Information Science
Architect at Wells Fargo [Wells Fargo Dealer Services -WFDS]
Blog: Profile

abhijit dot gadkari at gmail dot com
Irvine-92618,CA

## Comments and Discussions

 View All Threads First Prev Next
 What about Expression Trees tkrafael_net26-Jun-08 3:00 tkrafael_net 26-Jun-08 3:00
 Re: What about Expression Trees abhigad26-Jun-08 8:18 abhigad 26-Jun-08 8:18
 check out Charlie's blog post expression-tree-basics.aspxHe did a great job of collecting Links-to-LINQ at- Links-to-LINQ.aspx10 min's version on expression tree is “work in progress”. For any specific question - shoot an email on abhijit dot gadkari at gmail dot comThanks.abhi
 Re: What about Expression Trees abhigad5-Jul-08 18:07 abhigad 5-Jul-08 18:07
 Last Visit: 31-Dec-99 19:00     Last Update: 21-Jan-17 20:18 Refresh 1

General    News    Suggestion    Question    Bug    Answer    Joke    Praise    Rant    Admin

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.