Hi,
Is for
keyword obsolete or may become obsolete just as goto
in languages like C# or Java? In a few years, will it be strange and suspicious to see an object-oriented code which uses for
, like today, it's very suspicious to see goto
s?
In other words, is there any reason to know and use for
in programs?
I notice that there are a bunch of weaknesses with for
that doesn't exist when using foreach
:
'For' is rarely used and we rarely need it:
Don't know about scientific development, but to do general stuff, software products and websites not dealing especially with calculus, for
is used extremely rarely. I've seen and done many projects where there were no for loop in thousands of lines of code. Probably even when dealing with calculus, manipulating arrays, collections or matrices or ranges is something much more frequent, elegant and useful than a loop.
A few places when it seems that for
is required, in fact, it is not, and a collection-oriented solution may be used instead.
Reading source code of beginner developers, I also find for
used to do what .NET Framework already does. For example, to fill an array with the same value, repeated N times, some people will use a loop, when they must rather use Enumerable.Repeat()
.
Sometimes, I see that a loop is used to walk through an array, a collection or an enumerable. foreach
would be a much more elegant solution, and shorter to write.
'For' is not Jimmy-proof:
Probably I'm a very bad developer, but very often, when I use for
, I make the same mistake again and again: putting something other than a predefined variable in the loop range, like this:
int SomeValue
{
get
{
// Resources-expensive operation goes here.
}
}
for (int i = 0; i < this.SomeValue; i++)
{
// Code here.
}
// Instead, a less stupid developer would write:
int someValue = this.SomeValue;
for (int i = 0; i < someValue; i++)
{
// ...
}
Of course, what's wrong with that is that this.SomeValue
is called at each iteration, wasting resources. For example, this evening, I found a terrible mistake I've done: a loop used a 0..N range where N was a property making a query to a database. It was really surprising to see in the SQL Profiler than the same query was repeated 10 000 times.
'For' is ugly:
Maybe it's too subjective, but when manipulating collections all the time, what isn't a second solution more natural to write/read?
// Solution 1. C style.
for (int i = 0; i < 10; i++)
{
// Do something.
}
// Solution 2. Enumerable-oriented.
foreach (var i in Enumerable.Range(0, 10))
{
// Do something.
}
By the way, I find the second one easier to understand. Is a difference between:
for (i = 0; i < 10; i++)
for (i = 0; i <= 10; i++)
for (i = 1; i < 10; i++)
for (i = 1; i <= 10; i++)
easy to see? Whereas Enumerable.Range()
accepts only two parameters, which are extremely clear: the first one - where to start, and the number of elements.
What about more elaborate code?
foreach (string containingTwo in Enumerable.Range(0, 10).
Where(c => c.ToString().Contains('2')).
Select(c => c.ToString().PadLeft(8)))
{
Console.Write(containingTwo);
}
'For' is too rigid:
It's difficult to extend for
. Let's say we want to display a list of pages on a website without using ASP.NET paging control. The most obvious solution would be to display numbers with a for (int i = 1; i <= countPages; i++)
.
Now, what if the requirements change and we don't want to display every page, but only the first two, the last two, the current and the nearest pages to the current?
If we were using a collection, it would be easy to change. Actually, with a loop, it is not.
'For' is not Linq friendly:
There are plenty of things Linq can do, avoiding writing it by hand. But when we use for
, there is no place for Linq. If there is a filtering to do, we must do it ourselves. If the results must be converted, this must be done on a separate line. Yes, of course, lambda expressions can be used inside a simple loop too, but there is no an easy-to-read way to write all the stuff in a single, short line of code. Sum
or Average
are just not available, just as Join
or Except
or GroupBy
.