【发布时间】:2018-11-03 02:51:35
【问题描述】:
今天我看到了一段乍看之下很奇怪的代码,让我重新考虑。这是代码的简化版本:
if(list != null){
list.Clear();
list = null;
}
我的想法是,为什么不简单地替换它:
list = null;
我读了一点,我知道清除列表将删除对允许 GC 执行此操作但不会“调整大小”的对象的引用。为该列表分配的内存保持不变。
另一方面,设置为 null 也会删除对列表的引用(以及对它的项),也允许 GC 做这件事。
所以我一直在试图找出一个像第一个街区那样做的理由。我想到的一种情况是,如果您有两个对列表的引用。第一个块将清除列表中的项目,因此即使第二个引用仍然存在,GC 仍然可以清除为这些项目分配的内存。
不过,我觉得这有点奇怪,所以我想知道我提到的场景是否有意义?
另外,是否还有其他情况我们必须在将引用设置为 null 之前 Clear() 一个列表?
最后,如果我提到的场景是合理的,那么确保我们不会同时持有对该列表的多个引用以及我们将如何(明确地)这样做不是更好吗?
编辑:我明白清空列表和清空列表之间的区别。我很想知道 GC 内部是否有什么东西可以做到这一点,以便有理由在 Nulling 之前清除。
【问题讨论】:
-
作为一般规则,将其设置为
null是您通常应该做的。一旦 GC 意识到List不可访问 - 它将意识到其内容(即底层数组及其指向的内容)也是不可访问的。在某些情况下,清除它可能是值得的——例如,如果有多个对底层List的引用,并且您不只是想摆脱对List的引用,但您想确保所有other 引用指向一个空列表(正如您在问题中确定的那样)。公平地说,这种情况很少见。 -
wouldn't it be better off to just make sure we don't hold multiple references to this list at once and how would we do that (explicitly)除了通过作用域(即,将列表作为函数作用域或private,并且从不将其暴露在外部)之外,没有简单的方法可以做到这一点。 -
@mjwills 在这种情况下,它是私有的,只在类内部使用。
-
在这种情况下,它们是等价的。
-
在清空保存列表的变量之前立即调用
List.Clear()是没有用的如果这是对该列表的唯一引用。假设是这种情况,要么作者不知道这一点,要么他可能都混淆了List.Clear与其他Clear方法,这些方法是Dispose的同义词(在他们的类中)(例如,Stream.Dispose)和b) 因此认为List.Clear是一种“深层Dispose”,可以单独处理列表中的每个元素。
标签: c# .net icollection