2015-01-09 57 views
4

我知道從列表中刪除,而不是一個好主意,但如何獲得它的淺拷貝和迭代,而從原始列表中刪除?從列表中刪除,同時迭代它的一個淺表副本

例子:

public class myClass 
{ 
    public int id { get; set; } 
    public string name { get; set; } 
} 

List<myClass> list = new List<myClass>(); 

// getting a shallow copy with FindAll 
List<myClass> copy = list.FindAll(e => e.id > 10); 

for (int i = 0; i < copy.Count; i++) 
{ 
    // do stuff with copy[i] 
    list.RemoveAll(e => e.id == copy[i].id); 
} 

如果copy是隻是一個列表的元素的指針列表中,什麼將指針從複製點後,我從原來的列表中刪除?

+1

您要爲每個要刪除的項目調用'RemoveAll'一次。這沒有任何意義。只需調用'RemoveAll'一次即可刪除所有項目。 'list.RemoveAll(item => item.id> 10);'你就完成了。 – Servy 2015-01-09 21:35:48

+0

@Servy我不能,首先我需要做的東西與我刪除的項目。 RemoveAll實際上在if條件下。 – osmiumbin 2015-01-09 22:00:24

回答

11

當您從原始列表中刪除項目時,您不會從內存中刪除項目,而是將它們從列表中刪除,它們仍在內存中,並且copy已引用它們。

例如,考慮你是一所學校的學生,並且你正在參加數學和物理課程,如果數學老師從你班級中的學生名單中刪除了你,你仍然在物理班學生名單中,並且你仍然那所學校的學生!

listcopy都對內存中的某些項目有一些引用,您只是添加和刪除對它們的引用。如果你刪除了內存中所有對項目的引用,那麼垃圾收集器將從內存中刪除該項目。就像如果你不參加任何一所學校的課程,那麼你不再是該學校的學生了!

+1

非常好的比喻 – aw04 2015-01-09 21:18:56

4

更簡單(短):

foreach (var element in list.ToList()) 
{ 
    // do stuff with copy[i] 
    list.RemoveAll(e => e.id == element.id); 
} 

的LINQ ToList()創建上飛的臨時副本。

只要你使用不同於索引的列表元素(如你的例子中的一個ID)來訪問你的列表元素,你不必擔心改變索引。

+0

你也可以去反向迭代,這將保持索引完整,但是,這不是非常LINQ友好。 – 2015-01-09 21:15:53