2011-07-31 62 views
1

我正在編寫一個呼叫跟蹤應用程序,該應用程序命中了一個推送服務器,並獲取了一個JSON結果集的調用進來。在JSON對象中,有一個包含每個呼叫的logID。列表<String>不刪除項目

當新的呼叫進入時,我創建一個新的標籤頁並將一個呼叫對象與標籤頁標籤屬性相關聯。然後我檢查一個調用是否已被處置,如果推送服務器從Keys數組中刪除了logID。然後,我將Keys數組中的logIds與每個調用對象的logIds進行比較,該調用對象與每個打開的選項卡相關聯。

運行我的代碼時,它將從_psKeys列表中刪除logID,但在下一次迭代中將其添加回來。有人可以告訴我我做錯了什麼。

 var jsonResult = _pushServer.GetWebRequest(_pushServer.GetNewCallUrl(_locationID, _clientID)); 
     var jsonObject = _pushServer.GetJsonObject(jsonResult); 

     _tabKeys.Clear(); 
     _psKeys.Clear(); 

     // Load the tabKeys with all the keys for the open tabs. 
     foreach (TabPage tab in newCallTabControl.TabPages) 
     { 
      Call call = (Call)tab.Tag; 
      _tabKeys.Add(call.LogID);     
     } 

     // Load the Push Server Keys 
     foreach (string key in jsonObject.keys) 
     { 
      _psKeys.Add(key);     
     } 

     // Iterate over the keys and compare 
     foreach (string tabKey in _tabKeys) 
     { 
      foreach (string psKey in _psKeys) 
      { 
       if (! _tabKeys.Contains(psKey)) 
       { 
        // Remove the tab 
        foreach (TabPage tabPage in newCallTabControl.TabPages) 
        { 
         Call tabCallObject = (Call)tabPage.Tag; 
         if (tabCallObject.LogID == tabKey) 
         { 
          newCallTabControl.TabPages.Remove(tabPage);       
         } 
        } 
       }      
      }     
     } 
+1

這會更好的codereview stackexchange –

回答

1

你不應該從列表中刪除項目,你正在枚舉。首先我根本就沒有將它們添加....

var jsonResult = _pushServer.GetWebRequest(_pushServer.GetNewCallUrl(_locationID, _clientID)); 
    var jsonObject = _pushServer.GetJsonObject(jsonResult); 

    _tabKeys.Clear(); 
    _psKeys.Clear(); 
// Load the Push Server Keys 
    foreach (string key in jsonObject.keys) 
    { 
     _psKeys.Add(key);     
    } 
    var tabsToRemove = new List<TabPage>(); 
// Load the tabKeys with all the keys for the open tabs. 
    foreach (TabPage tab in newCallTabControl.TabPages) 
    { 
     Call call = (Call)tab.Tag; 
     if(_psKeys.Contains(call.LogID) 
     {    
      _tabKeys.Add(call.LogID); 
     }    
     else 
     { 
      tabsToRemove.Add(tab) 
     } 
    } 
    tabsToRemove.ForEach(t => newCallTabControl.TabPages.Remove(t)); 

,或者如果你不需要名單...

var tabsToRemove = newCallTabControl.TabPages 
      .Where(tab => !jsonObject.keys.Contains(((Call)tab.tag).LogID)) 
      .ToList(); 
tabsToRemove.ForEach(t => newCallTabControl.TabPages.Remove(t)); 
+0

我應該使用什麼來保存logId並進行比較?陣列會是更好的選擇嗎? –

+0

即使我刪除從_tabKeys列表中刪除項目的行,該列表也會被清除並從JSON結果自動填充,並提供相同的結果。 –

+0

我剛剛編輯了一下。從上下文中很難知道發生了什麼。這似乎有點令我費解 –

0

您正在修改一組正在迭代的集合。這絕不是一個好主意。

此外,就您的循環的邏輯而言,您似乎沒有在使用_psKeys進行迭代。應該是這樣的:

foreach (string tabKey in _tabKeys)   
{    
    if (! _psKeys.Contains(tabKey)) 
    { 
     //Remove the tab 
     //... 
    } 
} 
+0

你會推薦什麼? –

1

您可以使用LINQ讓你的數據需要進行操作,然後分別進行操作:

var tabKeysToRemove = _tabKeys.Where(t => !_psKeys.Contains(t)).ToList(); 
foreach (var tabKey in tabKeysToRemove) 
{ 
    _tabKeys.Remove(tabKey); 
    var tabsToRemove = newCallTabControl.TabPages 
     .Where(tp => ((Call)tp.Tag).logID == tabKey).ToList(); 
    tabsToRemove.forEach(t => newCallTabControl.TabPages.Remove(t)); 
} 
+0

這不會按原樣工作。由於LINQ的惰性,您仍然在迭代_tabKeys,同時從中刪除項目。您需要在每個LINQ鏈的末尾調用'.ToList()'來將刪除列表從原始列表中分離出來。 –

+0

@Andrew - 謝謝,很高興知道。我更新了我的答案。 – gilly3