This posting is part of an on-going series on LINQ – a critical tool for both Windows Phone and Silverlight Programmers.
I recently discovered LinqPad, a free utility developed by Joseph Albahari that supports Linq to Objects, Linq to SQL, Linq to Entity Framework and Linq to XML. You can use it to query virtually any source that you can query using LINQ in a C# program (e.g., oData, etc.) And you can use it to test any C# expression, statement or program.
[Click on image for full size]
Let’s take a look at how all this works by examining a simple Linq query against a list of integers. To start, we’ll open Visual Studio and create a console application. Here’s the source:
using System; using System.Collections.Generic; using System.Linq; namespace QueryAgainstListOfIntegers { internal class Program { private static void Main( string[ ] args ) { var list = new List<int>( ) { 1, 2, 3, 5, 7, 11, 13 }; var enumerable = from num in list where num < 6 select num; foreach ( var val in enumerable ) Console.WriteLine( val ); } } }
This small program actually illustrates a number of important things about LINQ and about features that appeared in C# 3.0 and 4.0. Before we begin an analysis, however, let’s take a look at extracting this example into LinqPad.
The only significant change you need to make is to change Console.WriteLine (used in Visual Studio Console Applications) to the built-in Dump method of LinqPad. Thus, in LinqPad you would set the language to C# Statements and you’d copy in the following code,
var list = new List<int>( ) { 1, 2, 3, 5, 7, 11, 13 }; var enumerable = from num in list where num < 6 select num; foreach ( var val in enumerable ) val.Dump();
Note that in LinqPad you do not need the using statements, nor the method structures; just the statements you want to run.
A Quick Examination of Fundamentals Illustrated In This Example
The first line could have been written
List<int> list = new List<int>( ) { 1, 2, 3, 5, 7, 11, 13 };
The results would have been identical. The advantages of the var keyword are that you avoid redundancy and that it is a bit terser. Further, there are times when you, as the programmer, may not know the type and letting the compiler infer the type (as is done with Var) can be a tremendous time saver (why look up the type when the compiler can figure it out?)
Make no mistake, however, variables and objects declared with var are type safe. If you were to hover your cursor over the variable name list, you’d find that it is of type List<int>.
Collection Initialization
Note also that we use initialization of the list; this is also a relatively new feature of C#. Again, we could have written this as,
var list = new List<int>(); list.Add(1); list.Add(2); list.Add(3); list.Add(5); list.Add(7); list.Add(11); list.Add(13);
Initialization is clearly more convenient and, to a degree, easier to maintain.
The Query Expression
The heart of this example is the query expression. The first line of the Linq query is a from statement, in this case creating the temporary variable number and indicating that we are selecting from a list of integers named list.
The second line is a where clause which narrows the answer space to those values that are less than six. The final line is a select statement (or projection) of the results.
The net effect of these three lines of code is that enumerable is an IEnumerable of integers that contains all of the values from list whose value is less than six.
IEnumerable
It is often pointed out that IEnumerable is the heart of Linq just as IObservable is the heart of Reactive Extensions (Rx). It is IEnumerable that allows you to create the foreach loop.
IEnumerable is an interface and classes that implement that interface will provide MoveNext(), Current and Reset().
Typically you can ignore this implementation detail, as you do when using foreach, but you can, in fact, rewrite the foreach loop using the IEnumerable operators:
var e = enumerable.GetEnumerator( ); while ( e.MoveNext( ) ) { Console.WriteLine( e.Current ); }
@Damien
Lambdas (and their ability to be treated either as Func or Expression are the real heart of LINQ. Being able to query stuff is useful, but only possible because of lambdas.
I’ve found LINQPad to be an indispensable tool in my developer’s toolkit. I use it much more as a code scratchpad than for querying data sources, although it’s quite capable for interacting with most data sources (SQL, Entity Framework, Azure, oData) as well.
Joseph Albahari is constantly adding helpful new features, and the LINQ samples he’s included are great for those just starting to learn LINQ.
I don’t mean to sound like too much of a fanboy, but this is one tool that’s had a bigger impact on me than most in recent memory (besides new releases of Visual Studio). Everyone should download it ASAP!
IQueryable is the real heart of LINQ. Being able to enumerate over stuff is useful but not the real power.
[)amien