質問

C#に逆列挙器を含めないという特定の理由や設計上の決定があるかどうかは誰もが知っていますか? C ++に相当する場合はとてもいいでしょう reverse_iterator 列挙器がC ++に相当するように iterator. 。逆方向に対応できるコレクションは、AireverseNumerableのようなものを実装するだけで、次のようなことができます。

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

このようにして、1つのリンクと他のリンクにインデクサーを使用するのではなく、同じ方法でリストとLinkedListsを反復することができます。

役に立ちましたか?

解決

これを実装することは完全に可能です。個人的には、私はほとんど逆転することはありません。これを行う必要がある場合は、最初に.Reverse()を呼び出します。おそらく、これは.NET BCLデザイナーも考えたことです。

すべての機能は、デフォルトでは実装されていません。それらを設計、実装、テスト、文書化、およびサポートする必要があります。 - レイモンドチェン

そして、これが、ユーティリティのほとんどを提供する機能を実装しない理由です。最も重要な機能(前面からバックの反復など)から始めます。そして、あなたはあなたの予算が枯渇しているか、あなたが思う場所のいずれかが継続する意味がない場所で停止します。

.NETベースクラスライブラリにはないものがたくさんあります。 .net 4まではありませんでした File.EnumerateLines. 。そして、私はそのような機能は、ほとんどの人にとって逆の反復よりも重要であると言いたいと思います。

逆の反復が一般的であるビジネスドメインで作業している場合があります。私の経験は反対です。フレームワークデザイナーとして、誰があなたのフレームワークを使用するか、そしてこれらの人々がどのような機能を要求するかを推測することしかできません。線を引くのは難しいです。

他のヒント

Ienumerableはフォワードのみのイテレーターであるため、利用できません。 movenext()メソッドのみがあります。これにより、インターフェイスは非常に普遍的であり、Linqの中核になります。それが必要なので、後方に反復することはできない現実世界のコレクションがたくさんあります 保管所. 。ほとんどのストリームは、たとえばそのようなものです。

LINQは、逆()拡張法を備えたソリューションを提供します。最初に要素を保存し、次にそれらを後方に繰り返すことで機能します。ただし、それは非常に無駄になる可能性があり、O(n)ストレージが必要です。既にインデックス可能なコレクションの最適化の可能性がありません。これを修正できます:

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

サンプルの使用法:

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

LinkedList <>を実装していないが、lindlistnode.previous Propertiesを介して迅速な後方反復を可能にするため、LinkedListの専門化を作成する必要があります。そのクラスを使用しない方がはるかに優れていますが、お粗末なCPUキャッシュローカリティがあります。安い挿入が必要ない場合は、常にリスト<>を好む。このように見えるかもしれません:

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

手がかりは、OPの最終行にあります。これをリストとLinkedListsで使用します。

だから、aの List, 、これはうまく機能します:

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

使用 IReadOnlyList それが何に取り組むかという点で、多くの柔軟性を与えます。

似たようなことが可能です LinkedLists.

ライセンス: CC-BY-SA帰属
所属していません StackOverflow
scroll top