Refactorings for converting loops: ForEach to For and back
Let’s take a look at the two CodeRush refactorings allowing us to convert a for-loop into foreach-loop, and a foreach-loop into for-loop, and compare these two loops to see what the difference is between them and which one is preferred.
The for-loop is useful for iterating over elements and for sequential processing. It uses an iteration variable and is good when iterating over many items sequentially with a precise condition of the iteration termination. No collection of elements is required, but we can use the iteration variable to index a separate collection. In its basic form, the loop contains three sections:
- An initialized iteration variable which specifies where to start;
- A condition for the loop termination;
- An iteration expression which modifies the iteration variable value.
The initialization, condition and iteration sections control how the loop will operate at run-time. Here is an example of a simple for-loop:
And one more example:
Notice that the second loop iterates over array items starting from the very first item until all items are cycled. In such cases, when you require to cycle through each object in an array or a collection and when each item should be processed in turn, the foreach-loop might be more preferred. When the foreach-loop is used, each item in the collection is processed in series until every item has been referenced, or the loop has been terminated by a break command. It has two sections instead of three as the for-loop:
- The type which determines the data type of the iterator during the loop’s execution.
- The collection section which names the collection or array that is to be cycled through.
Here is what it looks like if we cycle through the same numbers array as before:
Which is much easier to read then the same for-loop, isn’t it?
The For to ForEach refactoring allows you to automatically convert the for-loop that iterates over items of a collection or array into the simpler foreach-loop. Just place the editor caret on the for-loop and press the CodeRush shortcut, you will see the preview hint of the resulting code. Once the refactoring is applied, the loop type is converted without modifying the logic of the code:
However, sometimes when you need to modify the way the loop iterates over items, you might want to do the opposite operation – convert the foreach-loop into a for-loop, because the iteration variable in the for-loop provides more flexibility than a foreach-loop. Using the for-loop, you can iterate in a back order, or iterate over even indexes, or use other iterating algorithm, for example:
This loop increments the iteration variable by 2 each step of the loop. This means that the loop will iterate only over the even items of the array whereas the foreach-loop does not provide the capability to control which items and in which order are iterated. To help you to easily convert the foreach-loop into a for-loop, the opposite ForEach to For refactoring exists:
Which results in the equal implementation of the loop but using a different loop type.
There are several differences between two loops that might be interesting and should be considered while choosing the right loop type:
- The items of the collection or array cannot be modified inside the foreach-loop. The reason you cannot remove or add elements inside a foreach-loop is that the looping mechanism requires that the state is preserved. The runtime cannot verify if you removed or added an item that is to be looped over in a subsequent iteration. The for-loop does not have such a restriction, because you have a full control over the iteration algorithm.
- The speed of the loops iteration, which is critical in many applications. There are performance factors related to the for-loop. A foreach-loop has at best equivalent performance in regular looping conditions as the for-loop. The for-loop is often the fastest way to loop over a series of numbers as it does not require allocations on the managed heap and is easy for the compiler to optimize. When it goes to loop through, foreach-loop copies the current array to a new one for the operation. While for-loop doesn’t care of that part.
If you are planning to create high-performance code that is not iterating collections, it is better to use the for-loop. Even for collections, a foreach-loop is easier to read and understand, but it’s not that efficient as the for-loop. A foreach-loop can be used when writing less important parts of a program, as it reduces the complexity of the notation, but choose the for-loop for ‘hot’ loops as a precaution, and use the specific loop converting automated refactorings for this task.—– Products: CodeRush Pro Versions: 12.1 and up VS IDEs: 2008 and up Updated: Aug/28/2012 ID: R064