NOTA: Esta publicación terminó siendo mucho más detallada y, por lo tanto, fuera de tema, me disculpo.
Dicho esto, mis compañeros lo leen y creen que es valioso "en algún lugar". Este hilo no es el lugar. Agradecería sus comentarios sobre dónde debería ir esto (soy nuevo en el sitio).
De todos modos, esta es la versión C # en .NET 3.5, lo cual es sorprendente porque funciona en cualquier tipo de colección utilizando la semántica definida. Esta es una medida predeterminada (¡reutilización!), No el rendimiento o la minimización del ciclo de la CPU en el escenario de desarrollo más común, aunque eso nunca parece ser lo que sucede en el mundo real (optimización prematura).
*** Método de extensión que trabaja sobre cualquier tipo de colección y realiza una acción que el delegado espera un valor único del tipo, todo ejecutado sobre cada elemento a la inversa **
Requiere 3.5:
public static void PerformOverReversed<T>(this IEnumerable<T> sequenceToReverse, Action<T> doForEachReversed)
{
foreach (var contextItem in sequenceToReverse.Reverse())
doForEachReversed(contextItem);
}
¿Versiones anteriores de .NET o desea comprender mejor los componentes internos de Linq? Sigue leyendo .. O no ..
SUPUESTO: En el sistema de tipos .NET, el tipo Array hereda de la interfaz IEnumerable (no el IEnumerable genérico solo IEnumerable).
Esto es todo lo que necesita para iterar de principio a fin, sin embargo, desea moverse en la dirección opuesta. Como IEnumerable funciona en Array de tipo 'objeto', cualquier tipo es válido,
MEDIDA CRÍTICA: Asumimos que si puede procesar cualquier secuencia en orden inverso, es 'mejor' que solo podrá hacerlo en números enteros.
Solución a para .NET CLR 2.0-3.0:
Descripción: Aceptaremos cualquier instancia de implementación de IEnumerable con el mandato de que cada instancia que contiene sea del mismo tipo. Entonces, si recibimos una matriz, la matriz completa contiene instancias de tipo X. Si cualquier otra instancia es de un tipo! = X, se lanza una excepción:
Un servicio singleton:
clase pública ReverserService {private ReverserService () {}
/// <summary>
/// Most importantly uses yield command for efficiency
/// </summary>
/// <param name="enumerableInstance"></param>
/// <returns></returns>
public static IEnumerable ToReveresed(IEnumerable enumerableInstance)
{
if (enumerableInstance == null)
{
throw new ArgumentNullException("enumerableInstance");
}
// First we need to move forwarad and create a temp
// copy of a type that allows us to move backwards
// We can use ArrayList for this as the concrete
// type
IList reversedEnumerable = new ArrayList();
IEnumerator tempEnumerator = enumerableInstance.GetEnumerator();
while (tempEnumerator.MoveNext())
{
reversedEnumerable.Add(tempEnumerator.Current);
}
// Now we do the standard reverse over this using yield to return
// the result
// NOTE: This is an immutable result by design. That is
// a design goal for this simple question as well as most other set related
// requirements, which is why Linq results are immutable for example
// In fact this is foundational code to understand Linq
for (var i = reversedEnumerable.Count - 1; i >= 0; i--)
{
yield return reversedEnumerable[i];
}
}
}
public static class ExtensionMethods
{
public static IEnumerable ToReveresed(this IEnumerable enumerableInstance)
{
return ReverserService.ToReveresed(enumerableInstance);
}
}
[TestFixture] clase pública Testing123 {
/// <summary>
/// .NET 1.1 CLR
/// </summary>
[Test]
public void Tester_fornet_1_dot_1()
{
const int initialSize = 1000;
// Create the baseline data
int[] myArray = new int[initialSize];
for (var i = 0; i < initialSize; i++)
{
myArray[i] = i + 1;
}
IEnumerable _revered = ReverserService.ToReveresed(myArray);
Assert.IsTrue(TestAndGetResult(_revered).Equals(1000));
}
[Test]
public void tester_why_this_is_good()
{
ArrayList names = new ArrayList();
names.Add("Jim");
names.Add("Bob");
names.Add("Eric");
names.Add("Sam");
IEnumerable _revered = ReverserService.ToReveresed(names);
Assert.IsTrue(TestAndGetResult(_revered).Equals("Sam"));
}
[Test]
public void tester_extension_method()
{
// Extension Methods No Linq (Linq does this for you as I will show)
var enumerableOfInt = Enumerable.Range(1, 1000);
// Use Extension Method - which simply wraps older clr code
IEnumerable _revered = enumerableOfInt.ToReveresed();
Assert.IsTrue(TestAndGetResult(_revered).Equals(1000));
}
[Test]
public void tester_linq_3_dot_5_clr()
{
// Extension Methods No Linq (Linq does this for you as I will show)
IEnumerable enumerableOfInt = Enumerable.Range(1, 1000);
// Reverse is Linq (which is are extension methods off IEnumerable<T>
// Note you must case IEnumerable (non generic) using OfType or Cast
IEnumerable _revered = enumerableOfInt.Cast<int>().Reverse();
Assert.IsTrue(TestAndGetResult(_revered).Equals(1000));
}
[Test]
public void tester_final_and_recommended_colution()
{
var enumerableOfInt = Enumerable.Range(1, 1000);
enumerableOfInt.PerformOverReversed(i => Debug.WriteLine(i));
}
private static object TestAndGetResult(IEnumerable enumerableIn)
{
// IEnumerable x = ReverserService.ToReveresed(names);
Assert.IsTrue(enumerableIn != null);
IEnumerator _test = enumerableIn.GetEnumerator();
// Move to first
Assert.IsTrue(_test.MoveNext());
return _test.Current;
}
}