3

カスタム列挙を使用したリアルタイムの例を理解するために、さまざまな Web サイトにアクセスした後、この行を削除しています。私は例を得ました。しかし、それらは私を混乱に導きます。

テイク 1

class NumberArray
{
    public int[] scores;

    public NumberArray()
    {
    }

    public NumberArray(int[] scores)
    {
        this.scores = scores;
    }

    public int[] Scores
    {
        get {return scores;}
    }

}

テイク 2

public class Enumerator : IEnumerator
{
    int[] scores;
    int cur;
    public Enumerator(int[] scores)
    {
        this.scores = scores;
        cur = -1;
    }
    public Object Current
    {
        get {
            return scores[cur];
        }
    }

    public void Reset()
    {
        cur = -1;
    }

    public bool MoveNext()
    {
        cur++;
        if (cur < scores.Length)
            return true;
        else return false;
    }
}

public class Enumerable : IEnumerable
{
    int[] numbers;

    public void GetNumbersForEnumeration(int[] values)
    {
        numbers = values;
        for (int i = 0; i < values.Length; i++)
            numbers[i] = values[i];
    }

    public IEnumerator GetEnumerator()
    {
        return new Enumerator(numbers);
    }
}

主要

static void Main()
{
    int[] arr = new int[] { 1, 2, 3, 4, 5 };
    NumberArray num = new NumberArray(arr);
    foreach(int val in num.Scores)
    {
        Console.WriteLine(val);
    }

    Enumerable en = new Enumerable();
    en.GetNumbersForEnumeration(arr);

    foreach (int i in en)
    {
        Console.WriteLine(i);
    }
    Console.ReadKey(true);
}

テイク 2 では、カスタム イテレーションに従って、テイク 1 で行ったのと同じ整数配列をイテレートしました

おそらく、リアルタイムのカスタム反復の必要性を逃したのでしょう。既存の繰り返し機能ではできないタスクについて説明してもらえますか? (学校教育を終えたばかりなので、きちんと理解できるように簡単な例を挙げてください)。

更新: これらの例は、いくつかのサイトから取得しました。そのコードには特別なことは何もありません。カスタム反復を使用しなくても非常に簡単に実現できます。私の興味は、カスタム反復が非常に便利な実際のシナリオを知ることでした。

4

3 に答える 3

6

カスタム反復子は、反復するリソースがメモリに事前に読み込まれておらず、各反復で必要に応じて取得される場合に役立ちます。たとえば、LINQ to SQL で次のようなことを行う場合:

foreach(var employee in dataContext.Employees) {
    // Process employee
}

foreachループの各ステップで、データベースの Employees テーブルがクエリされ、次のレコードが取得されます。このように、ループを早期に終了すると、テーブル全体を読み取るのではなく、必要なレコードのみを読み取ることになります。

実際の例については、こちらを参照してください: enumerate lines on a file . foreachここでは、ループの各反復で各行がファイルから読み取られます。(ちなみに、.NET Framework 4 には、これと同じ機能が組み込まれています)。

于 2009-10-21T11:09:07.233 に答える
3

正直なところ、あなたが何を求めているのか完全にはわかりませんが、配列を返す (テイク 1 のように) とイテレータを返す (テイク 2) の違いが気になる場合は、これが私の答えです。

配列を返すこととイテレータを返すことには大きな違いがあります。配列を返すということは、内部状態を返すことを意味します (戻り値の一部としてコピーを作成する場合を除きますが、それはコストがかかります)。イテレータを返す場合は、呼び出し元が状態を反復できるようにする抽象化を返すだけです。これは、必要に応じて遅延評価を実行できることも意味します (配列を返す場合は明らかに実行できないことです)。

また、C# 2 でイテレータがサポートされているため、IEnumerable を手動で実装する理由はまったくありません。詳細については、この質問を参照してください

于 2009-10-21T11:09:45.793 に答える
2

過去にカスタム反復が役に立った別の例は、ツリー構造内のすべてのノードを再帰的に列挙する共通の抽象化を提供することでした...

foreach (Node n in tree)
  //...do something
于 2009-10-21T11:22:34.970 に答える