簡體   English   中英

從vb.net中的List(Of t)中刪除項目失敗

[英]Removing items from a List(Of t) in vb.net failing

我有一個通用列表,我正在使用List.Remove(Object)刪除項目。 我一直在刪除項目,但每當我到達第五項我刪除它失敗,並沒有從列表中刪除它。 我刪除的內容似乎並不重要,但每次我嘗試刪除第五項時失敗的五個項目。

可能是什么導致了這個? 查看List(Of T).Remove的文檔,它沒有指定他們用來刪除項目的算法。

Remove將基於在對象上調用.Equals來匹配。 默認情況下,對於給定對象,它只匹配同一個對象。 如果你想要兩個具有相同屬性的對象被認為是相等的,即使它們不是同一個對象,你需要覆蓋Equals方法並將邏輯放在那里。

但是,另一個好的選擇是使用RemoveAll並使用您要查找的條件傳入匿名委托或lambda表達式。 例如:

customers.RemoveAll(customer => customer.LastName.Equals(myCustomer.LastName));

當然,只有當你真的想要刪除所有匹配的項目時才有效,和/或如果你確定只有一個匹配項目。

如果您使用基於索引的方法從列表中刪除項目,並記住您刪除項目之后的項目索引將更改-1,因為您刪除它之前的項目。

您的清單中有多少項? 你如何刪除它們,只是循環? 請記住,這些是基於0的列表。 如果您正在使用整數進行任何類型的For循環,則可能無法正常刪除項目。

作為一般規則,您不應修改正在循環的集合,僅修改該集合中的項目。 刪除每個循環中的項目的問題是它更改了循環的集合並干擾列表計數和迭代位置。

常見的解決方案是:

  1. 向后循環集合,因此對迭代器的干擾不會影響執行
  2. 創建一個新集合,以便您可以修改一個集合並循環到另一個集合。

循環向后:

這是一個擴展方法,它接受Collection(Of T) (你可以使用List(Of T) ,但是list類已經暴露了一個RemoveAll方法,它基本上做了同樣的事情)。
我們將向后循環並根據傳入的lambda函數檢查集合中每個項目的有效性。 如果匹配,那么我們將刪除它。

<Extension()>
Public Sub RemoveEach(Of T)(ByRef col As Collection(Of T),
                            ByVal match As Func(Of T, Boolean))
    For i = col.Count - 1 To 0 Step -1
        If match(col(i)) Then col.RemoveAt(i)
    Next
End Sub

然后像這樣使用:

Dim col = New Collection(Of Integer)({1, 2, 3, 4}.ToList)
col.RemoveEach(Function(i) (i Mod 2) = 0)
'Produces list of 1 & 3

創建新集合:

跟蹤收集索引並使用RemoveAt而不是Remove刪除項目更有效,它接受一個對象,然后檢查集合的其余部分是否與該對象匹配。 但是,如果您真的想要一種方法來處理For循環中的項目,則可以在原始集合上調用ToList ,從而創建新列表。 然后,您可以遍歷新列表以查找需要從原始列表中刪除的項目。 每當您找到對象時,您都可以安全地將其從原始集合中刪除,因為它當前未被枚舉。

<Extension()>
Public Sub RemoveEachObject(Of T)(ByRef col As Collection(Of T), 
                                  ByVal match As Func(Of T, Boolean))
    For Each o As T In col.ToList()
        If match(o) Then col.Remove(o)
    Next
End Sub

有關詳細信息,請查看“foreach”循環中從列表中刪除這個很棒的答案

如果使用for循環刪除元素,則應考慮使用foreach,它更適合於集合,列表和可數對象

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM