Now that the March CTP is released, I wanted to blog about different ways you can use LINQ queries to simplify your code and write less code to achieve the same results.
Consider a typical application that has a collection of some type (say, a collection of Motorcycles). You want to generate a report of all motorcycles that are red and are built in the years 2006 or 2007. Let’s say that the data structure looks like this:
Class Motorcycle Private m_color As String Private m_year As Integer Public Sub New(ByVal color As String, ByVal year As Integer) Me.m_color = color Me.m_year = year End Sub Public ReadOnly Property Color() As String Get Return m_color End Get End Property Public ReadOnly Property Year() As Integer Get Return m_year End Get End Property End Class
If you had a collection of such items, you could foreseeably implement the reporting method like so:
Sub Report(ByVal list As IList(Of Motorcycle)) For Each x As Motorcycle In list If x.Color = "Red" And (x.Year = 2006 Or x.Year = 2007) Then Console.WriteLine(x.ToString()) End If Next End Sub
You can imagine that the reporting mechanism is more complete then WriteLine. Also, it is possible, although difficult, to create a new enumerable that has the filtered items; difficult because there are several design issues to consider. But it is possible to do it, and have the Report method assume that the list is already filtered. You would either have to implement a custom enumeration which filters elements as they are requested, or build a second list of elements.
This is where LINQ shines.
Imagine the Report function assumed that the list was already filtered (which is the right thing; messing business logic with presentation logic sucks). Now, with a small modification of the Report function, you can call the Report function very simply, without having to create custom enumerations or duplicating the lists yourself, using LINQ:
Sub Report(ByVal list As IEnumerable(Of Motorcycle)) For Each x As Motorcycle In list Console.WriteLine(x.ToString()) Next End Sub
Report(From c In list Where c.Color = "Red" And (c.Year = 2006 Or c.Year = 2007) Select c)
Woah! Isn’t that neat? You don’t need to do any messing around with enumerators, list management, etc. You just say, “give me the elements that I care about” and you get it.
The main design pattern that arises from LINQ is to prefer IEnumerable(Of T). This is because LINQ operates on IEnumerable(Of T), and if you design your application around IEnumerable(Of T), you will find many places where a LINQ query will provide an elegant solution to your problem.
What’s happening under the hood?
I won’t go into an indepth explanation of LINQ here; but I will simply say that using the power of LINQ, we were able to filter the list based on the conditions we wanted, and we selected the item that we wanted, and the items selected were returned as items were requested by the Report method.
Hopefully at a later time I will be able to delve deeper (or point you to blogs, articles, or videos) that discuss the inner workings of LINQ. For now, I hope that this example gives a little bit of an idea of the power of LINQ and how you can design your applications to take full advantage of LINQ, even if there are no databases in sight!