NOTA: questo post è finito per essere molto più dettagliato e quindi fuori tema, mi scuso.
Detto questo, i miei colleghi lo leggono e credono che sia prezioso "da qualche parte". Questo thread non è il posto giusto. Apprezzerei il tuo feedback su dove dovrebbe andare (sono nuovo nel sito).
Comunque questa è la versione C # in .NET 3.5 che è sorprendente in quanto funziona su qualsiasi tipo di raccolta utilizzando la semantica definita. Questa è una misura predefinita (riutilizzo!), Non la minimizzazione delle prestazioni o del ciclo della CPU nello scenario di sviluppo più comune, anche se non sembra mai essere ciò che accade nel mondo reale (ottimizzazione prematura).
*** Metodo di estensione che funziona su qualsiasi tipo di raccolta e esegue un'azione delegato che si aspetta un singolo valore del tipo, il tutto eseguito su ogni elemento al contrario **
Requisiti 3.5:
public static void PerformOverReversed<T>(this IEnumerable<T> sequenceToReverse, Action<T> doForEachReversed)
{
foreach (var contextItem in sequenceToReverse.Reverse())
doForEachReversed(contextItem);
}
Vecchie versioni .NET o vuoi capire meglio gli interni di Linq? Continua a leggere .. O no ..
ASSUNZIONE: Nel sistema di tipi .NET il tipo Array eredita dall'interfaccia IEnumerable (non IEnumerable generico, ma solo IEnumerable).
Questo è tutto ciò di cui hai bisogno per iterare dall'inizio alla fine, tuttavia vuoi muoverti nella direzione opposta. Poiché IEnumerable funziona su Array di tipo 'object', qualsiasi tipo è valido,
MISURA CRITICA: Partiamo dal presupposto che se è possibile elaborare qualsiasi sequenza in ordine inverso che è "migliore", quindi essere in grado di farlo solo su numeri interi.
Soluzione a per .NET CLR 2.0-3.0:
Descrizione: accetteremo qualsiasi istanza di implementazione di IEnumerable con il mandato che ogni istanza in essa contenuta sia dello stesso tipo. Quindi, se riceviamo un array, l'intero array contiene istanze di tipo X. Se altre istanze sono di un tipo! = X viene generata un'eccezione:
Un servizio singleton:
public class 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] public class 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;
}
}