Add counters to foreach loops #8318
Replies: 7 comments 8 replies
-
Theoretically, the new I personally like this proposal as it could be trivially lowered to a either a dedicated counter or a for loop: for (int i = 0; i < src.Length; i++)
{
T element = src[i];
// …
} |
Beta Was this translation helpful? Give feedback.
-
What is the expected behavior if the number of elements overflows the max value of the counter variable? |
Beta Was this translation helpful? Give feedback.
-
I feel like the whole reason ForEach exists is because sometimes you just want to iterate without a counter. If you need a counter, For loops already exists Making a ForEach look almost exactly like a For would seem to add complexity without payoff, as For loops will always perform better if you need a counter. |
Beta Was this translation helpful? Give feedback.
-
See: #1584 |
Beta Was this translation helpful? Give feedback.
-
IEnumerable<int> enumer = [4, 8, 10, 14];
foreach (var (item, index) in enumer.Select((item, index) => (item, index)))
{
Console.WriteLine("Item " + index + ":" + item);
} |
Beta Was this translation helpful? Give feedback.
-
The addition of the foreach (var (index, item) in source.Index())
{ } |
Beta Was this translation helpful? Give feedback.
-
I was curious if this is really worth it and have created benchmark, which tries manual increment vs. .NET 9's Index (internally an iterator state-machine) vs. a custom struct-based implementation. Here's the results on my machine:
Of course the benchmark is rather simple and there is still room for improvement in my custom implementation, which I would like to defer to someone more knowledgeable in IEnumerator optimization tricks. My personal conclusion is that a language feature is definitely NOT worth the effort, because the difference is minimal and existing features can be used paired with JIT magic to achieve very good results. I hope that LDM agrees with this and we can get some optimizations done on the Enumerable.Index implementation, which is currently not optimized compared to other parts of LINQ, which perform a lot of magic tricks. Here the code I used for my benchmark. Feel free to experiment!
|
Beta Was this translation helpful? Give feedback.
-
The problem
I often find myself writing something of the form like this:
When using arrays you can just do:
But this does not work for any kind of enumerators as...
a
needs to have a Length propertyProposal
Add the possibility to define an optional counter in the foreach loop definition:
(Maybe the
=0
part could be omitted, but I don't know if it fits the language.)The counter variable is initialized at the beginning of the foreach loop and incremented by 1 after every iteration.
The type of the counter has to be
IBinaryInteger<TSelf>
Syntax
Beta Was this translation helpful? Give feedback.
All reactions