J
James Curran
I'd like to make the following proposal for a new feature for the C#
language. I have no connection with the C# team at Microsoft. I'm posting
it here to gather input to refine it, in an "open Source" manner, and in an
attempt to build a ground-swell of support to convince the folks at
Microsoft to add it.
Proposal: "first:" "last:" sections in a "foreach" block
The problem:
The foreach statement allows iterating over all the elements of a
collection. However, often the first or last element of the collection must
be handled differently than the others in the collection. For example, if
we were generating a list of items for display, we'd want a comma after
every item except the last. In these cases, foreach cannot be used, and the
alternates which can be used are generally ugly and often less efficient
than foreach. An elegant solution keeping with the concept of C# is needed.
The proposal:
I suggest adding four new keywords (only available inside foreach block) to
direct the compiler to our exact intentions. "first:" "last:" "other:"
"all:"
Example:
foreach (Person p in personCollection)
{
first:
Console.WriteLine("Names: {0},", p.Name");
other:
Console.WriteLine(" {0},", p.Name");
last:
Console.WriteLine(" {0}", p.Name");
}
A block not preceeded by one of those keywords would be assumed to be an
"all:" block, exact as is the case now.
Analysis:
The advantages of the feature:
It solves a problem in an elegant way, keeping with the design concepts of
C#.
It is handled entirely by the compiler, so that it has ZERO effect on code
that does not use it, and it requires no changes to the class framework or
the CLR. (These were problems with other suggested solutions for this)
The disadvantages:
It requires four keywords, although this could be reduced to three
(eliminating "all:") and, they would each be very context sensitive, so the
conflicts with user-defined identifiers is unlikely.
Implementation:
Presently, a foreach construct is largely "syntactic sugar" around a while
loop using an IEnumerator, such that code written as
foreach (int i in arry)
{
Console.WriteLine(i);
}
Would be compiled much as if it were written:
IEnumerator n = arry.GetEnumerator();
while(n.MoveNext())
{
int i = (int) n.Current;
Console.WriteLine(i);
}
Similarly, code using these blocks would also have a direct translation:
foreach (int i in arry)
{
First:
Console.WriteLine("{0} - first", i);
Others:
Console.WriteLine(i);
}
Would be compiled as:
IEnumerator n = arry.GetEnumerator();
if (n.MoveNext())
{
int i = (int) n.Current;
Console.WriteLine("{0}-- first ", i);
while(n.MoveNext())
{
i = (int) n.Current;
Console.WriteLine(i);
}
}
(The internal representation of a "last:" block is a bit more involved, but
still basically straightforward)
Any comments are suggestion would be appreciated.
Truth,
James Curran
MVP (for .um. VC++)
language. I have no connection with the C# team at Microsoft. I'm posting
it here to gather input to refine it, in an "open Source" manner, and in an
attempt to build a ground-swell of support to convince the folks at
Microsoft to add it.
Proposal: "first:" "last:" sections in a "foreach" block
The problem:
The foreach statement allows iterating over all the elements of a
collection. However, often the first or last element of the collection must
be handled differently than the others in the collection. For example, if
we were generating a list of items for display, we'd want a comma after
every item except the last. In these cases, foreach cannot be used, and the
alternates which can be used are generally ugly and often less efficient
than foreach. An elegant solution keeping with the concept of C# is needed.
The proposal:
I suggest adding four new keywords (only available inside foreach block) to
direct the compiler to our exact intentions. "first:" "last:" "other:"
"all:"
Example:
foreach (Person p in personCollection)
{
first:
Console.WriteLine("Names: {0},", p.Name");
other:
Console.WriteLine(" {0},", p.Name");
last:
Console.WriteLine(" {0}", p.Name");
}
A block not preceeded by one of those keywords would be assumed to be an
"all:" block, exact as is the case now.
Analysis:
The advantages of the feature:
It solves a problem in an elegant way, keeping with the design concepts of
C#.
It is handled entirely by the compiler, so that it has ZERO effect on code
that does not use it, and it requires no changes to the class framework or
the CLR. (These were problems with other suggested solutions for this)
The disadvantages:
It requires four keywords, although this could be reduced to three
(eliminating "all:") and, they would each be very context sensitive, so the
conflicts with user-defined identifiers is unlikely.
Implementation:
Presently, a foreach construct is largely "syntactic sugar" around a while
loop using an IEnumerator, such that code written as
foreach (int i in arry)
{
Console.WriteLine(i);
}
Would be compiled much as if it were written:
IEnumerator n = arry.GetEnumerator();
while(n.MoveNext())
{
int i = (int) n.Current;
Console.WriteLine(i);
}
Similarly, code using these blocks would also have a direct translation:
foreach (int i in arry)
{
First:
Console.WriteLine("{0} - first", i);
Others:
Console.WriteLine(i);
}
Would be compiled as:
IEnumerator n = arry.GetEnumerator();
if (n.MoveNext())
{
int i = (int) n.Current;
Console.WriteLine("{0}-- first ", i);
while(n.MoveNext())
{
i = (int) n.Current;
Console.WriteLine(i);
}
}
(The internal representation of a "last:" block is a bit more involved, but
still basically straightforward)
Any comments are suggestion would be appreciated.
Truth,
James Curran
MVP (for .um. VC++)