HINWEIS: Dieser Beitrag war viel detaillierter und daher nicht thematisch. Ich entschuldige mich.
Davon abgesehen lesen meine Kollegen es und glauben, dass es "irgendwo" wertvoll ist. Dieser Thread ist nicht der richtige Ort. Ich würde mich über Ihr Feedback freuen, wohin dies führen soll (ich bin neu auf der Website).
Auf jeden Fall ist dies die C # -Version in .NET 3.5, die insofern erstaunlich ist, als sie mit der definierten Semantik für jeden Sammlungstyp funktioniert. Dies ist eine Standardmaßnahme (Wiederverwendung!), Nicht die Leistung oder die Minimierung des CPU-Zyklus im gängigsten Entwicklungsszenario, obwohl dies in der realen Welt niemals der Fall zu sein scheint (vorzeitige Optimierung).
*** Erweiterungsmethode, die über einen beliebigen Sammlungstyp arbeitet und einen Aktionsdelegierten ausführt, der einen einzelnen Wert des Typs erwartet, die alle in umgekehrter Reihenfolge über jedes Element ausgeführt werden **
Anforderungen 3.5:
public static void PerformOverReversed<T>(this IEnumerable<T> sequenceToReverse, Action<T> doForEachReversed)
{
foreach (var contextItem in sequenceToReverse.Reverse())
doForEachReversed(contextItem);
}
Ältere .NET-Versionen oder möchten Sie Linq-Interna besser verstehen? Lesen Sie weiter .. Oder nicht ..
ANNAHME: Im .NET-Typsystem erbt der Array-Typ von der IEnumerable-Schnittstelle (nicht von der generischen IEnumerable, sondern nur von IEnumerable).
Dies ist alles, was Sie brauchen, um von Anfang bis Ende zu iterieren, aber Sie möchten sich in die entgegengesetzte Richtung bewegen. Da IEnumerable mit einem Array vom Typ 'Objekt' funktioniert, ist jeder Typ gültig.
KRITISCHE MASSNAHME: Wir gehen davon aus, dass Sie eine Sequenz in umgekehrter Reihenfolge verarbeiten können, die "besser" ist, als dies nur für ganze Zahlen möglich ist.
Lösung a für .NET CLR 2.0-3.0:
Beschreibung: Wir akzeptieren jede IEnumerable-Implementierungsinstanz mit dem Mandat, dass jede darin enthaltene Instanz vom gleichen Typ ist. Wenn wir also ein Array erhalten, enthält das gesamte Array Instanzen vom Typ X. Wenn andere Instanzen vom Typ! = X sind, wird eine Ausnahme ausgelöst:
Ein Singleton-Service:
öffentliche Klasse 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] öffentliche Klasse 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;
}
}