質問

大丈夫、この非常に単純なボタンで始めましょうクリック方法

    private void button1_Click(object sender, EventArgs e)
    {
        int counter = 1;
        List<int> items = new int[] { 1, 2, 3 }.ToList();
        List<int>.Enumerator enm = items.GetEnumerator();

        // 1
        if (!enm.MoveNext())
            throw new Exception("Unexpected end of list");
        if (enm.Current != counter)
            throw new Exception(String.Format("Expect {0} but actual {1}", counter, enm.Current));
        counter++;

        // 2
        if (!enm.MoveNext()) 
            throw new Exception("Unexpected end of list");
        if (enm.Current != counter) 
            throw new Exception(String.Format("Expect {0} but actual {1}", counter, enm.Current));
        counter++;

        //3
        if (!enm.MoveNext())
            throw new Exception("Unexpected end of list");
        if (enm.Current != counter)
            throw new Exception(String.Format("Expect {0} but actual {1}", counter, enm.Current));
        counter++;

        if (enm.MoveNext()) 
            throw new Exception("Unexpected continuation of list");
    }
.

この方法は、すべてのアサーションが正常に通過するので何もしません。冗長性を除去する方法を紹介する方法を紹介する必要があると信じるまでは問題ありません。

    static void AssertNext(ref int counter, List<int>.Enumerator e)
    {
        if (!e.MoveNext()) 
            throw new Exception("Unexpected end of list");
        if (e.Current != counter) 
            throw new Exception(String.Format("Expect {0} but actual {1}", counter, e.Current));
        counter++;
    }

    private void button2_Click(object sender, EventArgs e)
    {
        var counter = 1;
        var items = new int[] { 1, 2, 3 }.ToList();
        var enm = items.GetEnumerator();
        AssertNext(ref counter, enm);
        AssertNext(ref counter, enm);
        AssertNext(ref counter, enm);
        if (enm.MoveNext()) throw new Exception("Unexpected continuation of list");
    }
.

としても、このリファクタリングは簡単です(少なくとも)。プログラムを破る! assertnextへの2番目の呼び出しでは、列挙子が開始点に既にリセットされているように見え、アサーションを失敗させます。

何が起こるのか理解できません。私は本当にこのパズルと初心者のように感じます。

ここで何が恋しいの?

役に立ちましたか?

解決

List.Enumeratorが構造体であることを想像しています。あなたはそれを操作してから戻ってくるメソッドにそれを渡しています。操作はおそらくあなたの元のインスタンスのために起こらなかったでしょう。

他のヒント

List<T>.Enumeratorは、メソッドを離れて変更してから、メソッドのローカルの範囲にコピーされ、その後破壊される値型です。参照でそれを渡してみてください。

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