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.
Uh oh!
There was an error while loading. Please reload this page.
Uh oh!
There was an error while loading. Please reload this page.
-
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