2012-07-03 132 views
1

我有以下代碼。如何迭代通過更改集合

private void LoopThroughDependsIssues(JIRAOperations jiraOps, string jiraURL, string token, string username, string password, string projectKey, string exportTargetPath, string branch, SVNOperations svnOps, string svnExePath, string changesetDBFile, DependencyManager mgr) 
     { 
      var tempVar = mgr.Dependencies; 
      foreach (var item in tempVar) 
      { 
       if (item.depends.Length > 0) 
       { 
        var templist = item.depends; 
        var listissues1 = templist.Split(','); 
        for (var i = 0; i < listissues1.Length-1; i++) 
        { 
         var newissue1 = new string[] { listissues1[i].ToString() }; 
         newissue1.getChangeSet(jiraOps, jiraURL, token, username, password, projectKey, exportTargetPath, branch, svnOps, svnExePath, changesetDBFile, mgr); 
        } 
        //throw new Exception("Dependencies found"); 
       } 
      } 
     } 

在此,我正在迭代通過mgr.Dependencis集合。此值在newissue1.getChangeSet(jiraOps, jiraURL, token, username, password, projectKey, exportTargetPath, branch, svnOps, svnExePath, changesetDBFile, mgr); 中變化因此,對於此方法的每次調用,我的收集值都在增加。但第一次它工作正常。但在第二次迭代時,它給予例外,如

收集被修改;枚舉操作可能不會執行。

我認爲這個例外即將改變集合。如何處理這種情況。

我的班級定義如下。

public class Dependency 
    { 
     public string issueID { get; set; } 
     public string jirastatus { get; set; } 
     public int dependencyFound { get; set; } 
     public string depends { get; set; } 
     public string linked_issues { get; set; } 
     } 

     public class DependencyManager 
     { 
      public List<Dependency> Dependencies { get; private set; } 
      public DependencyManager() 
      { 
       this.Dependencies = new List<Dependency>(); 

      } 
} 
+0

您可以將迭代器包裝在一個對象中,該對象可以檢查並檢測對基礎集合的更改。但是這比它的價值更麻煩。你最好不要爲此煩惱,而且在迭代時不要修改集合。 –

+0

@ Jeff ..但需要在這裏添加新的值。爲了增加新的值,它應該再次運行循環。 – Searcher

+0

這聽起來像是你想要一次做太多。考慮將其分解成兩個函數 - 一個是將依賴關係提取到一個簡單的ID字符串列表,另一個函數將ID列表中的項目加載到列表中。 – overslacked

回答

5

如果索引到Dependencies收集就不會出現一個枚舉創建,您可以通過爲集合被修改循環。如果新項目未附加到列表末尾或項目被刪除,則此方法很容易導致頭痛。

for(int i = 0; i < mgr.Dependencies.Count; i++) 
{ 
    var item = mgr.Dependecies[i]; 
    if (item.depends.Length > 0) 
    { 
     // code unchanged 
    } 
} 

一種安全的方法是使用一個Queue並與mgr.Dependencies要處理的初始項目,然後Enqueue任何其他項目來填充它。

var toBeProcessed = new Queue<Dependency>(mgr.Dependencies); 
while(toBeProcessed.Count > 0) 
{ 
    var item = toBeProcessed.Dequeue(); 

    // loop 

    // if a new dependency gets added that needs processing, just add it to the queue. 
    toBeProcessed.Enqueue(newissue1); 

} 
+0

@Mike ..謝謝邁克。但是當我嘗試使用我的代碼時,這是令人困惑的。你可以申請這個我的代碼請.. ..! – Searcher

+0

@YSSS我澄清了第一個例子。實際上,除非您有權訪問您要處理的新Dependency對象,否則第二個示例不可行。我沒有仔細閱讀,認爲'newissue1'是'Dependency'類型。 –

+0

否.. newissue1不只是一個字符串[]類型。我們使用newissues1調用一些擴展方法。而已。 – Searcher

2

如果你想要的僅僅是使用集合,因爲它是在一開始,而不關心的變化,你可以把收集的快照:

var tempVar = mgr.Dependencies.ToList(); //This will create a new list with the same items 
foreach (var item in tempVar) { 
    ... 
} 
-2

可以遍歷如果你不使用foreach,而是使用正則循環。如果您只在最後添加行到修改後的集合中,則只需很少的更改即可使用。

 var tempVar = mgr.Dependencies; 
     var cnt = tempvar.Count(); // Only iterate items available when we start 

     for (int i = 0; i < cnt; i++) 
     { 
      var item = tempVar[i]; 
+1

如果通過刪除項目在中間插入來修改集合,該怎麼辦?這不是一個好的解決方案 – ivowiblo

+0

當然這不是一個好的解決方案,如果你刪除或插入到中間。這是如果你只在最後添加行。在這種情況下,它是完美的。所以根據你的代碼的不同,這可能是一個隻影響或改變的解決方案。我將添加答案以更好地反映這一點。 – IvoTops

+0

但是你說「只有在我們開始時迭代可用項目」並且這不是真的 – ivowiblo