No está disponible porque IEnumerable es un iterador de solo reenvío. Solo tiene un método MoveNext(). Eso hace que la interfaz sea muy universal y el núcleo de Linq. Hay muchas colecciones del mundo real que no se pueden repetir al revés porque eso requiere almacenamiento. La mayoría de las transmisiones son así, por ejemplo.
Linq proporciona una solución con el método de extensión Reverse(). Funciona al almacenar los elementos primero, y luego iterarlos hacia atrás. Sin embargo, eso puede ser muy inútil, requiere O (n) almacenamiento. Falta una posible optimización para colecciones que ya son indexables. Que se puede solucionar: el uso
static class Extensions {
public static IEnumerable<T> ReverseEx<T>(this IEnumerable<T> coll) {
var quick = coll as IList<T>;
if (quick == null) {
foreach (T item in coll.Reverse()) yield return item;
}
else {
for (int ix = quick.Count - 1; ix >= 0; --ix) {
yield return quick[ix];
}
}
}
}
muestra:
var list = new List<int> { 0, 1, 2, 3 };
foreach (var item in list.ReverseEx()) {
Console.WriteLine(item);
}
Usted querrá hacer una especialización para LinkedList ya que no implementa IList <> pero todavía permite rápida hacia atrás iteración a través de la Última y propiedades LinkedListNode.Previous. Aunque es mucho mejor no usar esa clase, tiene una ubicación de caché de CPU pésima. Siempre favor de la Lista <> cuando no necesite inserciones baratas.Se podría tener este aspecto:
public static IEnumerable<T> ReverseEx<T>(this LinkedList<T> list) {
var node = list.Last;
while (node != null) {
yield return node.Value;
node = node.Previous;
}
}
Interesante pregunta, 'MoveNext()' parece un poco una contradicción para un empadronador inversa aunque supongo que para la compatibilidad con '' foreach' la GetReverseEnumerator() 'método sería en realidad todavía tienen que devolver un 'IEnumerator' y por lo tanto requeriría ese método, incluso si' MovePrevious() 'parece más apropiado para mi mente – RobV
Existe el método de extensión Reverse linq que logra algo similar ... – RQDQ
En los tipos que implementan' IList 'obtenemos un 'Reverse' eficiente de linq. Lamentablemente, no todos los tipos que pueden implementar 'Reverse' de manera eficiente, también pueden implementar' IList '. Por ejemplo, una lista doblemente vinculada. Así que estoy de acuerdo en que esas colecciones que tengan un método 'Reverse()' incorporado, serían agradables. –
CodesInChaos