2011-01-31 43 views
2

我需要通過源函數(它返回IEnumerable)的結果通過其他處理函數的列表(每個函數返回IEnumerable)。奇怪的代表參考行爲

一切都很好,但我還需要允許處理函數在其輸入枚舉上執行多個循環。

因此,而不是通過IEnumerable<T>,我想我會改變輸入參數爲Func<IEnumerable<T>>,並允許每個功能重新啓動enumerable,如果需要的話。

不幸的是,我現在得到一個堆棧溢出,其中最後的處理函數正在調用它自己,而不是將請求傳遞迴鏈中。

示例代碼有點人爲設計,但希望能讓您瞭解我想要實現的目標。

class Program 
{ 
    public static void Main(string[] args) 
    { 
     Func<IEnumerable<String>> getResults =() => GetInputValues("A", 5); 

     List<String> valuesToAppend = new List<String>(); 

     valuesToAppend.Add("B"); 
     valuesToAppend.Add("C"); 

     foreach (var item in valuesToAppend) 
     { 
      getResults =() => ProcessValues(() => getResults(),item); 
     } 

     foreach (var item in getResults()) 
     { 
      Console.WriteLine(item); 
     } 

    } 

    public static IEnumerable<String> GetInputValues(String value, Int32 numValues) 
    { 
     for (int i = 0; i < numValues; i++) 
     { 
      yield return value; 
     } 
    } 

    public static IEnumerable<String> ProcessValues(Func<IEnumerable<String>> getInputValues, String appendValue) 
    { 
     foreach (var item in getInputValues()) 
     { 
      yield return item + " " + appendValue; 
     } 
    } 

} 

回答

4

getResults捕獲爲可變,而不是一個值。我真的不喜歡你用這裏(似乎令人費解),但你應該能夠通過改變捕獲固定計算器的總體思路:

foreach (var item in valuesToAppend) 
    { 
     var tmp1 = getResults; 
     var tmp2 = item; 
     getResults =() => ProcessValues(() => tmp1(),tmp2); 
    } 

在一個側面說明:IEnumerable[<T>]已經還挺重複的,你只需撥打foreach另一個時間 - 是是IEnumerator[<T>]是(儘管Reset())不是 - 而且,我認爲這是值得做試圖做到這一點沒有需要永遠重複計數,因爲在一般情況下,根本無法保證工作。


這裏有一個簡單的(IMO)實現同樣的結果:

using System; 
using System.Collections.Generic; 
using System.Linq; 
class Program { 
    public static void Main() { 
     IEnumerable<String> getResults = Enumerable.Repeat("A", 5); 
     List<String> valuesToAppend = new List<String> { "B", "C" }; 
     foreach (var item in valuesToAppend) { 
      string tmp = item; 
      getResults = getResults.Select(s => s + " " + tmp); 
     } 
     foreach (var item in getResults) { 
      Console.WriteLine(item); 
     } 
    } 
} 
+0

第一個例子避免了計算器,但現在返回:ACC,ACC等 – rob 2011-01-31 09:55:48