Factor Mystic

6Jan/092

A Quick Lesson In Overengineering

I was tapping out a quick for-fun project where I wanted to iterate through all the letters in the alphabet.

//other logic
foreach(char letter in //hmm...

I didn't really want to manually initialize an array new char[]{"A", "B", "C" and I recalled how other languages have shortcuts for building lists, like ["A".."Z"]. It's called "List Comprehension" and it's available in a lot of cool languages.

So I began to think about how to accomplish this in C#. The .. syntax obviously didn't work. Googling the topic brought me to Wikipedia, which lists a couple of examples using Enumerable.Range.

"Okay," I mused, "I can build on that easily!" Enumerable.Range(65, 26) will be the starting point since "A" is ASCII 65, and there are 26 letters in the alphabet. If I can just convert each one of these to a char, I'm golden. The function I found was ConvertAll, but that's a LINQ extension method for the List<T> type. No problem, all I need is Enumerable.Range(65, 26).ToList().ConvertAll. It's simple to convert an int to its char by casting, so my implementation of List Comprehension in C# for the alphabet was

Enumerable.Range(65, 26).ToList().ConvertAll(delegate(int value) { return (char)value; })

 

Check it out, it works great, what a clever programmer I am!

foreach(char letter in Enumerable.Range(65, 26).ToList().ConvertAll(delegate(int value) { return (char)value; }))
{
//breakpoint here to confirm
}

 

And now, the moral of the story: In C#, the String class implements IEnumerable<char>. Which means that all I needed to do was write:

foreach(char letter in "ABCDEFGHIJKLMNOPQRSTUVWXYZ")
{
//how about that
}

It's so much simpler, shorter, and it's instantly understandable. Learn from me, don't be an overengineer!

 

P.S. I could have saved myself the embarassment if I had remembered that the only reasonable numbers you should see in source code are 0, 1, and 2.

 

Special thanks to the #cobol crew for showing me the error of my ways.

  • Donald Trump

    Your solution is crap. Enumerable.Range is much better, but you ruined it through overengineering, and then proposed a solution to that, which is underengineered. Here is one right answer:

    const char FirstChar = 'A';
    const char LastChar = 'Z';
    foreach (char c in Enumerable.Range(FirstChar, LastChar – FirstChar + 1)) /* do whatever you want with these chars */

  • Whitey

    I liked it