.NET Developments

Sep 2 2008   5:14PM GMT

Iterators, Lambda, and LINQ… Oh My!

Brein Matturro Profile: Brein Matturro

Since the creation of the .Net Framework, Microsoft has kept the concept of “Type Safe” at the forefront of their design goals.  When 1.1 shipped, the framework had a “generic” collection type called an ArrayList that seemed to break this goal.  Microsoft quickly went above and beyond with the 2.0 framework by adding Generics and Anonymous Methods to the mix.  Anonymous methods coupled with Generics paved the way to Lambda expressions, Extension methods,  and LINQ (Language INtegrated Query).  The topic of this paper is loosely defined as:  The path to understanding Lambda and LINQ.

What came first?

Iterating through a collection with a for-each construct has been around for a long time.  .Net has the capability and in the beginning it was the recommended way of looping through a collections of widgets to find something or count something.  The basic construct is:

        private int CountForEach()
        {
            int count = 0;
            foreach (DLDog Dog in Dogs)
            {
                if (Dog.FoodBrand == "Purina" )
                {
                    count++;
                }
            }
            return count;
        }

Nothing too earth shattering about this.  Assuming we have a collection of 10 dogs and 3 of them use “Purina”, we will return a count of 3.

How would Generics and Anonymous methods change this syntax?  In the .Net 2.0 framework we can simplify the previous code a little as follows:

        private int CountGenericDelegate()
        {
            MyActionCount = 0;
            Dogs.ForEach(MyAction);
            return MyActionCount;
        }

This is a little misleading because we still need to write the delegate method “MyAction” but it does give us some flexibility in that we can pass any method to the ForEach generic method that adheres to the Action<T> prototype which is a predefined delegate in .Net 2.0.  Here is what the MyAction needs to look like in this example:

        private void MyAction(DLDog Dog)
        {
            if (Dog.FoodBrand == "Purina" )
            {
                MyActionCount++;
            }
        }

Another predefined delegate is the Predicate<T> delegate.  This one returns a Boolean based on some condition.  The <T> is typically your List<T> type.  Here is an example that uses the Predicate<T>:

        private List<DLDog> QueryDelegate()
        {
            return Dogs.FindAll(ByTypeAndCost);
        }
        // Predicate<T> typed method for FindAll
        bool ByTypeAndCost(DLDog Dog)
        {
            if (Dog.DogType == "German Sheperd" && Dog.AnnualVet > 1500M)
                return true;
            else
                return false;
        }

Enter .NET 3.5 – SWEEEET!

In .NET 3.5 Microsoft pulled all punches and really exploited the power of delegates, generics, and anonymous methods.  Building on that technology they added extension methods, lambda, and LINQ to the system.  Now our first count example can be simplified as:

        private int CountLambda()
        {
            MyActionCount = 0;
            return Dogs.Count(n => n.FoodBrand == "Purina" );
        }

This syntax is foreign as you can see but after a short explanation it will become very natural.  The “=>” operator is loosely defined as “Goes To”.  Under the covers – the compiler is doing this:

        private int CountLambda()
        {
            this.MyActionCount = 0;
            return this.Dogs.Count<DLDog>(delegate(DLDog n)
            {
                return (n.FoodBrand == "Purina" );
            });
        }

Previous code sample courtesy of “Reflector“…

Lambda is nothing more than syntactic sugar for inline anonymous methods and the .Count method on a generic list is nothing more than an extension method provided by the .Net 3.5 framework to the .Net 2.0’s generic list class.  No smoke and mirrors here!

Now LINQ is another animal but simply exploits everything up to this point and the previous example looks like:

        private int CountLinq()
        {
            var query = from dog in Dogs select dog;
            return query.Count(n => n.FoodBrand == "Purina" );
        }

The query variable is of type IEnumerable<T> and the T in this case is a DLDog object.  The compiler ends up with the following:

        private int CountLinq()
        {
            return this.Dogs.Select<DLDog, DLDog>(
                delegate(DLDog dog)
                {
                    return dog;
                }).Count<DLDog>(
                delegate(DLDog n)
                {
                    return (n.FoodBrand == "Purina" );
                }
                );
        }

Notice the use of the .Select extension method.  The method is defined as:

      public static IEnumerable<TResult> Select<TSource, TResult>(
            this IEnumerable<TSource> source,
            Func<TSource, TResult> selector)

(In the Visual Studio help system… )

So in summary – LINQ is really syntactic sugar for the extension methods provided by the .NET 3.5 framework!  Simple! 
…and SWEEEET!

Send me an email if you want a copy of the source code used for this article.

 Comment on this Post

 
There was an error processing your information. Please try again later.
Thanks. We'll let you know when a new response is added.
Send me notifications when other members comment.

REGISTER or login:

Forgot Password?
By submitting you agree to receive email from TechTarget and its partners. If you reside outside of the United States, you consent to having your personal data transferred to and processed in the United States. Privacy

Forgot Password

No problem! Submit your e-mail address below. We'll send you an e-mail containing your password.

Your password has been sent to: