对范围内的每个索引执行一些操作

Tro*_*ton 2 c# ienumerable foreach c#-8.0

C# 8.0 引入了结构体System.IndexSystem.Range

循环 a 的最简洁的方法是什么System.Range

var owners = new string[] {"Alice", "Bob", "Charlie"};
var pets = new string[] {"Dog", "Cat", "Bird"};

foreach (var index in 1..3) {
    var pet = pets[index];
    var owner = owners[index];
    Console.WriteLine($"{owner} owns a {pet}");
}
Run Code Online (Sandbox Code Playgroud)

上面这行foreach (var index in 1..3) {是编译错误。

类型“System.Range”不能在“foreach”语句中使用,因为它既没有实现“IEnumerable”或“IEnumerable”,也没有合适的“GetEnumerator”方法,其返回类型具有“Current”属性和“MoveNext”方法

Tim*_*ter 11

恐怕您无法枚举 a System.Range(您可以,请参阅我的编辑),因为它没有实现IEnumerable<int>. 原因是它可能包含集合末尾的索引。

如果您愿意,您需要使用for-loop 或Enumerable.Range

foreach (var index in Enumerable.Range(0, 3)) {
    var pet = pets[index];
    var owner = owners[index];
    Console.WriteLine($"{owner} owns a {pet}");
}
Run Code Online (Sandbox Code Playgroud)

如果您想要的只是获取同一索引处的两个集合的项目,请使用Dmitry所示的Enumerable.Zip方法。


编辑:实际上你可以使用扩展来完成(此处鸣谢,请注意我的错误修复)

public static class RangeEx
{
    public static RangeEnumerator GetEnumerator(this Range range)
    {
        if (range.Start.IsFromEnd || range.End.IsFromEnd)
        {
            throw new ArgumentException(nameof(range));
        }

        return new RangeEnumerator(range.Start.Value, range.End.Value);
    }

    public struct RangeEnumerator : IEnumerator<int>
    {
        private readonly int _end;
        private int _current;

        public RangeEnumerator(int start, int end)
        {
            _current = start - 1; // - 1 fixes a bug in the original code
            _end = end;
        }

        public int Current => _current;
        object IEnumerator.Current => Current;

        public bool MoveNext() => ++_current < _end;

        public void Dispose() { }
        public void Reset()
        {
            throw new NotImplementedException();
        }
    }
}
Run Code Online (Sandbox Code Playgroud)

这样你就可以使用你的代码:

foreach (int index in 1..3)
{
    Console.WriteLine($"{owners[index]} owns a {pets[index]}");
}
Run Code Online (Sandbox Code Playgroud)