在谷歌搜索后,我发现了这个讨论:
Possible to iterate backwards through a foreach?
但是在答案中有使用扩展方法.Reverse()。反向,对象列表,即。字符串列表,首先要反转,foreach不会以我的理解来反转列表吗?如果我得到了列表" Cat"," Dog",并使用.Reverse() - 方法,列表将是" Dog"," Cat&# 34;和foreach从0元素开始直到lenght-1元素,这就是我不想要的东西。我想知道,如果有任何方法可以反转foreach迭代顺序,从lenght-1开始下降到0.
答案 0 :(得分:1)
如果有任何方法可以反转
foreach
迭代次序,从长度-1开始下降到0
不适用于List<T>
。 GetEnumerator()
的实现返回一个从头到尾枚举的枚举器 - 没有办法覆盖它。
使用自定义集合,您只需使用可以向后移动的其他枚举器,但无法覆盖{{1使用。
答案 1 :(得分:1)
Reverse
方法copy the list first:
public static IEnumerable<TSource> Reverse<TSource>(this IEnumerable<TSource> source) {
if (source == null) throw Error.ArgumentNull("source");
return ReverseIterator<TSource>(source);
}
static IEnumerable<TSource> ReverseIterator<TSource>(IEnumerable<TSource> source) {
Buffer<TSource> buffer = new Buffer<TSource>(source);
for (int i = buffer.count - 1; i >= 0; i--) yield return buffer.items[i];
}
但你可以自己做一个扩展方法:
public static IEnumerable<TSource> Backwards<TSource>(this IList<TSource> source) {
for (var i = source.Count - 1; i >= 0; --i)
yield return source[i];
}
然后像这样使用它:
foreach (var item in array.Backwards())
Console.WriteLine(item); // Or whatever else
或者,当然,你可以做同等的事情:
for (var i = array.Length - 1; i >= 0; --i)
Console.WriteLine(array[i]); // Or whatever else
答案 2 :(得分:1)
您可以实现一个向后迭代列表的枚举器。这样,您可以使用foreach
而无需更改原始列表或创建副本。
public class ReverseEnumerator<T> : IEnumerator<T> {
private IList<T> _list;
private int _index;
private T _current;
public ReverseEnumerator(IList<T> list) {
_list = list;
Reset();
}
public IEnumerator<T> GetEnumerator() {
return this;
}
public T Current {
get {
if (_index < 0 && _index >= _list.Count) throw new InvalidOperationException("Enumeration has not started. Call MoveNext.");
return _current;
}
}
public void Dispose() { }
object IEnumerator.Current { get { return Current; } }
public bool MoveNext() {
bool ok = --_index >= 0;
if (ok) _current = _list[_index];
return ok;
}
public void Reset() {
_index = _list.Count;
}
}
用法示例:
int[] a = { 1, 2, 3, 4, 5 };
foreach (int x in new ReverseEnumerator<int>(a)) {
Console.WriteLine(x);
}