Frage

Weiß jemand, ob es einen bestimmten Grund oder eine bestimmte Entscheidung gab, keinen umgekehrten Enzerrator in C#aufzunehmen? Es wäre so schön, wenn es ein Äquivalent zum C ++ gäbe reverse_iterator Genau wie Enumerator ist das Äquivalent des C ++ - iterator. Sammlungen, die umgekehrt werden können, würden nur so etwas wie ireverseveryerable implementieren und man könnte so etwas tun wie:

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

Auf diese Weise können Sie Listen und LinkedListen auf die gleiche Weise iterieren, anstatt den Indexer für einen und früheren Links für den anderen zu verwenden, wodurch eine bessere Abstraktion erreicht wird

War es hilfreich?

Lösung

Es wäre durchaus möglich, dies zu implementieren. Persönlich bin ich fast nie umgekehrt. Wenn ich das tun muss, rufe ich zuerst .Reverse () an. Wahrscheinlich haben dies auch die .NET -BCL -Designer auch gedacht.

Alle Funktionen sind standardmäßig nicht implementiert. Sie müssen entworfen, implementiert, getestet, dokumentiert und unterstützt werden. - Raymond Chen

Aus diesem Grund implementieren Sie keine Funktionen, die wenig Nutzen bieten. Sie beginnen mit den wichtigsten Funktionen (z. Und Sie halten irgendwo an, wo entweder Ihr Budget erschöpft ist oder wo Sie denken, dass es nicht sinnvoll ist, fortzufahren.

Es gibt viele Dinge, die sich nicht in der Bibliothek der Basisklasse der .NET befinden. Bis .NET 4 dort war sogar nicht ein File.EnumerateLines. Und ich würde sagen, dass eine solche Funktionalität für die meisten Menschen wichtiger ist als umgekehrte Iteration.

Es kann sein, dass Sie in einem Geschäftsbereich arbeiten, in dem die umgekehrte Iteration üblich ist. Meine Erfahrung ist das Gegenteil. Als Framework -Designer können Sie nur raten, wer Ihr Framework verwenden und welche Funktionen diese Personen verlangen werden. Es ist schwer, die Linie zu zeichnen.

Andere Tipps

Es ist nicht verfügbar, weil iEnumerable nur Iterator vorwärts ist. Es hat nur eine moveNext () -Methode. Das macht die Schnittstelle sehr universell und den Kern von Linq. Es gibt viele reale Kollektionen, die nicht rückwärts iteriert werden können, da dies erfordert Lagerung. Die meisten Streams sind zum Beispiel so.

LINQ liefert eine Lösung mit der Reverse () -Erweiterungsmethode. Es funktioniert, indem es zuerst die Elemente speichert und sie dann rückwärts iteriert. Das kann jedoch sehr verschwenderisch sein, es erfordert eine Aufbewahrung von O (n). Es fehlt eine mögliche Optimierung für Sammlungen, die bereits indexierbar sind. Was Sie reparieren können:

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

Stichprobenverbrauch:

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

Sie möchten eine Spezialisierung für LinkedList vornehmen, da es ILIST <> nicht implementiert, aber dennoch eine schnelle Rückwärts -Iteration über die letzten und linkedListNode. -previous -Eigenschaften ermöglicht. Obwohl es viel besser ist, diese Klasse nicht zu verwenden, hat es eine miese CPU -Cache -Lokalität. Bevorzugt die Liste <> immer, wenn Sie keine billigen Einsätze benötigen. Es könnte so aussehen:

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

Der Hinweis befindet sich in der endgültigen Zeile des OP: Verwenden Sie diese auf Listen und LinkedLists.

Also für a List, Dieser würde gut funktionieren:

    public static IEnumerable<T> AsReverseEnumerator<T>(this IReadOnlyList<T> list)
    {
        for (int i = list.Count; --i >= 0;) yield return list[i];
    }

Verwendung IReadOnlyList Geben Sie viel Flexibilität in Bezug auf das, woran es arbeiten wird.

Ähnliches wäre möglich für LinkedLists.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top