2012-10-27 52 views
0

我試圖通過集合產生迭代,如果集合是空的,則調用一個將獲得下一組結果的增量方法。如果增量表示沒有更多的結果,那麼產量有中斷;在使用yield時遞增IEnumerator/IEnumerable

我不能使用(我認爲)帶有MoveNext()等的標準IEnumerator,因爲增量方法返回兩種不同類型的數據。

我已經嘗試過下面的例子,但它在一次迭代後停止。我希望有一個更簡單的方法來做到這一點(或者至少可能只是我有一個錯誤)。

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; 
     } 
    } 
} 
+0

這是一個[XY問題(HTTP://www.perlmonks .ORG/index.pl?NODE_ID = 542341)? –

回答

1

你只q2列表中添加元素。因此,當你調用Q1迭代器,你正在檢查

if (q1.Any()) 

後退出它,當你調用Q2迭代器,你以後

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

只執行一次這foreach循環退出它,它返回只有三個項目其中添加到q2期間單個Increment調用Q1迭代器。

這不是很清楚你想要達到的目標,但這裏是你可以使用循環產生的迭代器返回值的方式

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; 
    } 
} 
+0

雖然Increment的yielding方法是我的一個糟糕的例子(不應該在SO的午夜!),但是你確實讓我在正確的軌道上說我的迭代器提前退出。 –