see remarks para method example cref comment c# enumerator

remarks - ¿Por qué no hay ReverseEnumerator en C#?



remarks c# (2)

¿Alguien sabe si hubo una razón específica o una decisión de diseño para no incluir un enumerador inverso en C #? Sería tan bueno si hubiera un equivalente al reverse_iterator C ++, de la misma manera que el Enumerador es el equivalente del iterator C ++. Las colecciones que pueden ser iteradas inversamente solo implementarían algo como IReverseEnumerable y uno podría hacer algo como:

List<int>.ReverseEnumerator ritr = collection.GetReverseEnumerator(); while(rtir.MoveNext()) { // do stuff }

De esta manera, podría iterar listas y listas enlazadas de la misma manera en lugar de utilizar un indexador para uno y enlaces anteriores para el otro, logrando así una mejor abstracción


No está disponible porque IEnumerable es un iterador de sólo avance. 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 iterar hacia atrás porque eso requiere almacenamiento . La mayoría de las corrientes son así, por ejemplo.

Linq proporciona una solución con el método de extensión Reverse (). Funciona almacenando los elementos primero, luego iterándolos hacia atrás. Sin embargo, eso puede ser muy inútil, requiere almacenamiento O (n). Falta una posible optimización para las colecciones que ya se pueden indexar. Que se puede arreglar:

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]; } } } }

Uso de la muestra:

var list = new List<int> { 0, 1, 2, 3 }; foreach (var item in list.ReverseEx()) { Console.WriteLine(item); }

Querrá hacer una especialización para LinkedList ya que no implementa IList <> pero aún así permite una rápida iteración hacia atrás a través de las propiedades Last y LinkedListNode.Previous. Aunque es mucho mejor no usar esa clase, tiene una mala ubicación de caché de CPU. Siempre favorece Lista <> cuando no necesites inserciones baratas. Podría verse así:

public static IEnumerable<T> ReverseEx<T>(this LinkedList<T> list) { var node = list.Last; while (node != null) { yield return node.Value; node = node.Previous; } }


Sería totalmente posible implementar esto. Personalmente, casi nunca lo invierto. Si necesito hacer esto, llamo a .Reverse () primero. Probablemente esto es lo que pensaron los diseñadores de .NET BCL también.

Todas las características no están implementadas por defecto. Deben ser diseñados, implementados, probados, documentados y respaldados. - Raymond Chen

Y es por esto que no implementas características que proporcionan poca utilidad. Comienzas con las características más importantes (como iterar de frente a atrás). Y se detiene en algún lugar donde su presupuesto se agota o donde cree que no tiene sentido continuar.

Hay muchas cosas que no están en la biblioteca de clases base .NET. Hasta .NET 4 ni siquiera había un File.EnumerateLines . Y me atrevería a decir que tal funcionalidad es más importante que la iteración inversa para la mayoría de las personas.

Podría ser el caso de que esté trabajando en un dominio de negocios donde la iteración inversa es común. Mi experiencia es lo contrario. Como diseñador de marcos, solo puede adivinar quién usará su marco y qué características demandarán estas personas. Es difícil trazar la línea.