How do you get the index of the current iteration of a foreach loop?

后端 未结 30 1681
刺人心
刺人心 2020-11-22 07:05

Is there some rare language construct I haven\'t encountered (like the few I\'ve learned recently, some on Stack Overflow) in C# to get a value representing the current iter

30条回答
  •  既然无缘
    2020-11-22 07:43

    This answer: lobby the C# language team for direct language support.

    The leading answer states:

    Obviously, the concept of an index is foreign to the concept of enumeration, and cannot be done.

    While this is true of the current C# language version (2020), this is not a conceptual CLR/Language limit, it can be done.

    The Microsoft C# language development team could create a new C# language feature, by adding support for a new Interface IIndexedEnumerable

    foreach (var item in collection with var index)
    {
        Console.WriteLine("Iteration {0} has value {1}", index, item);
    }
    
    //or, building on @user1414213562's answer
    foreach (var (item, index) in collection)
    {
        Console.WriteLine("Iteration {0} has value {1}", index, item);
    }
    

    If foreach () is used and with var index is present, then the compiler expects the item collection to declare IIndexedEnumerable interface. If the interface is absent, the compiler can polyfill wrap the source with an IndexedEnumerable object, which adds in the code for tracking the index.

    interface IIndexedEnumerable : IEnumerable
    {
        //Not index, because sometimes source IEnumerables are transient
        public long IterationNumber { get; }
    }
    

    Later, the CLR can be updated to have internal index tracking, that is only used if with keyword is specified and the source doesn't directly implement IIndexedEnumerable

    Why:

    • Foreach looks nicer, and in business applications, foreach loops are rarely a performance bottleneck
    • Foreach can be more efficient on memory. Having a pipeline of functions instead of converting to new collections at each step. Who cares if it uses a few more CPU cycles when there are fewer CPU cache faults and fewer garbage collections?
    • Requiring the coder to add index-tracking code, spoils the beauty
    • It's quite easy to implement (please Microsoft) and is backward compatible

    While most people here are not Microsoft employees, this is a correct answer, you can lobby Microsoft to add such a feature. You could already build your own iterator with an extension function and use tuples, but Microsoft could sprinkle the syntactic sugar to avoid the extension function

提交回复
热议问题