2nd
I’ve been asked recently to explain the advantages of using LINQ and the Extension Methods available in Visual Studio 2008 with C# 3.5.
I have trouble explaining this. It came to me as one of the “Eureka” moments. The best way for someone to learn it, is just to see it. So, I’m going to head back to my earliest memories of coding and an taste of what I see.
In introductions to programming, a simple problem is often repeated. It is probably because we see the problem in different variations constantly while coding. Given a set of data, perform an action based on each element in the set.
Specifically, I’m going to take an array of integers (1 to 10) and write each one to the console.
When I started programming, the GOSUB was not yet introduced (Yes, I learnt to program in BASIC). So to solve the problem, we coded the following logic:
1: static void GotoLoop(int[] data)
2: {
3: //Initialize the loop
4: //Zero based Array
5: int currentIndex = 0;
6: //Or some form of terminating indicator
7: int end = data.Length;
8: //A placeholder reference for what is currently being worked on.
9: int currentData;
10: //Run the loop
11: start:
12: //Do something with current item
13: currentData = data[currentIndex];
14: Console.WriteLine(currentData);
15: //Finalize the loop
16: currentIndex++;
17: //Run Gaurd statement
18: if (currentIndex < end) {
19: goto start;
20: }
21: }
</PRE< DIV>
Looking at the code, it seems a wonder anyone ever got anything done. That’s a lot of plumbing to repeat a single action. Let alone the potential spots for errors. It is step for step (or as close as I was going to produce for this post) what instructions the computer is going to use to handle this problem.
To mitigate some of the plumbing problems, language designers create a new syntax for this issue. The For Loop:
1: static void ForLoop(int[] data)
2: {
3: //Or some form of terminating indicator
4: int end = data.Length;
5: //Or some form of terminating indicator
6: int currentData;
7: //Zero based Array
8: //Run Gaurd statement
9: //Finalize the loop
10: for (int currentIndex = 0; currentIndex < end; currentIndex++)
11: {
12: //Do something with current item
13: currentData = data[currentIndex];
14: Console.WriteLine(currentData);
15: }
16: }
</PRE< DIV>
Same amount of logic, same potential for errors. However, here the code groups the code required to enumerate the array is placed all in the same line, creating a separation of logic. This makes diagnosing and finding bugs easier.
Along with the advances in OOP, the idea of encapsulation came along. So a few new ways of limiting this came about. An Iterator interface was created to wrap data structure like array, with methods hasNext and Next to eliminate much of the plumbing from the code.
This expanded into an System.Collections.IEnumerable interface which allows a new construct of the ForEach statement.
1: static void ForEachLoop(int[] data)
2: {
3: foreach (int currentData in data)
4: {
5: //Do something with current item
6: Console.WriteLine(currentData);
7: }
8: }
</PRE< DIV>
So now, we’ve gone from 18 line function to a 6 line function. So this is a built-in syntax that allows for much more abstraction, more power per command.
Now, what about commands not built into the language? Wouldn’t it be nice if you build a method like:
1: data.ForEach(Console.WriteLine);
</PRE< DIV>
Originally posted on RapidMind Solution’s Blog