0

コレクションを反復処理しようとしています。コレクションが空の場合は、次の結果セットを取得するインクリメント メソッドを呼び出します。インクリメントがこれ以上結果がないことを示すと、ブレーク付きの歩留まりになります。

インクリメントメソッドは2つの異なるタイプのデータを返すため、MoveNext()などで標準のIEnumeratorを使用することはできません(私はそう思います)。

以下の例を試しましたが、1回繰り返すと停止します。これを行うためのはるかに簡単な方法があることを願っています(または、少なくともバグがあるだけで可能です)。

static void Main(string[] args)
{
    var query = new Query();

    foreach(var s in query.Q1())
    {
        Console.WriteLine(s);
    }

    foreach (var s in query.Q2())
    {
        Console.WriteLine(s);
    }

    Console.ReadLine();
}

public class Query
{
    int i = 0;
    bool complete;
    List<string> q1 = new List<string>();
    List<string> q2 = new List<string>();

    public IEnumerable<string> Q1()
    {
        if (complete)
        {
            yield break;
        }
        if (!q1.Any() && !complete)
        {
            Increment();
        }
        if (q1.Any())
        {
            foreach (var s in q1)
            {
                yield return s;
            }
        }
    }

    public IEnumerable<string> Q2()
    {
        if (complete)
        {
            yield break;
        }
        if (!q2.Any() && !complete)
        {
            Increment();
        }
        if (q2.Any())
        {
            foreach (var s in q2)
            {
                yield return s;
            }
        }
    }

    void Increment()
    {
        if (i < 10)
        {
                    // simulate getting two types of data back (parent and two children) from datasource
            q1.Add((1 * (i + 1)).ToString());
            q2.Add("A: " + (1 * (i + 1)).ToString());
            q2.Add("B: " + (1 * (i + 1)).ToString());

            i++;
        }
        else
        {
            complete = true;
        }
    }
}

結果:

1
A: 1
B: 1

これを行うためのより良い方法、またはどこが間違っているかについてのアイデアはありますか?

編集

これが私の大まかな準備ができた修正です:

public IEnumerable<string> Q1()
{
    var index = 0;

    if (!complete)
    {
        while (!complete)
        {
            var count = q1.Count();

            if (index + 1 == count)
            {
                for (var x = index; index < count; index++)
                {
                    yield return q1[index];
                }
            }
            else
            {
                Increment();
            }
        }
    }
    else
    {
        foreach (var s in q1)
        {
            yield return s;
        }
    }
}
4

1 に答える 1

1

リストにのみ要素を追加していq2ます。Q1したがって、イテレータを呼び出すと、チェック後に終了します

if (q1.Any())

イテレータを呼び出すときはQ2、後で終了します

if (q2.Any())
{
     foreach (var s in q2)
     {
         yield return s;
     }
}

このforeachループは 1 回だけ実行され、イテレータの 1 回の呼び出しq2中に追加された 3 つの項目のみを返します。IncrementQ1

達成したいことはあまり明確ではありませんが、ループを使用してイテレータの戻り値を生成する方法は次のとおりです

public IEnumerable<string> Q2()
{
    for (int i = 1; i <= 10; i++) // start from 1
    {
        yield return i.ToString(); // do not multiply by 1
        yield return "A: " + i;    // .ToString() is not necessary 
        yield return "B: " + i;
    }
}
于 2012-10-27T23:22:38.200 に答える