Why Doesn’t LINQ Perform?

I’m not talking about speed / performance, LINQ is plenty fast for my needs. I’m wondering why linq can’t perform any ACTIONs, why it can’t DO anything.

Yes, I understand, its called “Language Integrated Query” because it is meant to be used as a way to ASK questions, not PERFORM operations.

That is all fine and dandy, but, despite its name, LINQ is actually a set manipulation language more than anything else. It is a language for working with entire sets of things in a uniform way.

Let’s get serious here, in 90% of cases, immediately following a LINQ query, we see a foreach statement that iterates over the items. Often times, this loop has only a single action inside of it. For instance:

var itemsThatQualify =
	from i in itemList
	where i.hasSomeQuality()
	select i;

foreach(var item in itemsThatQualify)
{
	Item.doSomething();
}

Its getting to the point where I am getting tempted to perform the Query inside of the foreach statement instead of before it. But I think the result is less readable, what do you think? …

foreach(var item in (
	from i in itemList
	where i.hasSomeQuality()
	select i))
{
	item.doSomething();
}

The best thing I can say about that is that it DOESN’T look like english at all. In fact, the lambda version of this statement is actually more readable because it is less wordy…

foreach(var item in itemList.Where(i => i.hasSomeQuality()))
{
	item.doSomething();
}

It ain’t great, but its a bit better than the last thing. But the first one is still more self-documenting.

I’m getting to the point where I wish I could do this…

from i in itemList
where i.hasSomeQuality()
perform i.doSomething();

I actually typed that out at work the other day and said “why did they NOT make that work?” That is elegant, and would save streamline tons of repetitive coding.

Then, the wheels got turning. LINQ is written using Templates and Extension methods. hmm. Both of those are available to me for building my own stuff. Why not write my own LINQ Extension called “Perform”… Here it is, complete with a Main function that shows it off.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

namespace LinqPerform
{
    public static class LinqExtension
    {
        public delegate void Proc(T arg);

        public static void Perform(
            this IEnumerable source,
            Proc performer)
        { foreach (TSource item in source) performer.Invoke(item); }
    }

    class Program
    {
        static void Main(string[] args)
        {
            // something enumarable to work with
            var intList = new List { 0, 1, 2, 3, 4, 5 };

            // DoSomething() with each element
            intList.Perform(i => Console.Out.WriteLine(i));

            // get a little tricker (evens only)
            Console.Out.WriteLine(); // a visual break
            intList.Where(i => i % 2 == 0)
                .Perform(i => Console.Out.WriteLine(i));

            // get a little wordier (with odds only)
            Console.Out.WriteLine(); // a visual break
            (from i in intList
             where i % 2 == 1 //odds only
             select i
            ).Perform(i => Console.Out.WriteLine(i));

            // do a little more, VERY little more
            Console.Out.WriteLine(); // a visual break
            intList.Where(i => i % 2 == 0)
                .Perform(i =>
                {
                    Console.Out.Write(i.ToString() + " ");
                    Console.Out.Write((i+1).ToString() + " ");
                    Console.Out.WriteLine();
                });

            // wait for a return key
            Console.In.ReadLine();
        }
    }
}

It Worked!!! I cant believe it.
Now if I could only get native queryable support…

from i in intList
where i % 2 == 1
perform Console.Out.WriteLine(i);

would look so much better than…

(from i in intList
 where i % 2 == 1 //odds only
 select i
).Perform(i => Console.Out.WriteLine(i));

But I guess I can make due.

Did you enjoy this post? Why not leave a comment below and continue the conversation, or subscribe to my feed and get articles like this delivered automatically to your feed reader.

Comments

No comments yet.

Leave a comment

(required)

(required)