以下代码之间有什么区别
代码1:
if(RecordCollections!=null){
RecordCollections.Clear();
RecordCollections=null;
}
代码2:
RecordCollections = null;
代码存在于Dispose
方法中,在将Collection设置为null之前,使用Clear方法有什么优势吗?是否需要它?
答案 0 :(得分:3)
在将Collection设置为null之前,使用Clear方法是否有任何优势。
没有好的Minimal, Complete, and Verifiable code example就不能说。
那就是说,这些代码片段对我来说都不是很有用。如果Clear()
方法所做的只是清空集合,那么第一个肯定是毫无意义的。当然,如果它真的经历过,例如在每个集合成员上调用Dispose()
,这将是不同的。但这将是一个非常不寻常的集合实现。
即使是第二个也没有什么价值,并且与正常的IDisposable
语义相反。 IDisposable
应该仅用于管理非托管资源。它有时用于其他事情,但这是它的主要目的。特别是,通常只在丢弃对象之前调用Dispose()
。如果对象本身将被丢弃,那么它将保留给其他对象(例如集合)的任何引用将不再可访问,因此将它们设置为null
并没有任何有用的效果。
事实上,在某些情况下,将变量设置为null
实际上可以扩展对象的生命周期。运行时非常复杂,可以识别变量不再使用,如果它保留了对象的最后一个剩余引用,则该对象可以在该点符合垃圾收集条件,即使变量的范围进一步扩展。通过将变量设置为null
,变量本身将在稍后的程序中使用,因此运行时不能将其视为无法访问,直到该点为止,晚于其他方式。
最后一点通常最常用于局部变量,而不是对象中的字段。但从理论上讲,运行时可以更广泛地进行优化。这是一个不好的习惯,进入设置null
变量,这些变量本身不会更长。
答案 1 :(得分:1)
Dispose
是指明确清理un-managed memory
的机制,因为无法使用标准Garbage Collector
清除,大多数IDisposable
将由类实施,它在内部使用非托管API,如Database Connection
。
标准做法是:
同时实现Finalizer
,因为Dispose
是一个显式调用,如果被调用者遗漏,那么Finalization确实会处理清理操作,尽管它需要2个循环的GC
如果一个类使用任何一个对象,作为一个实现Dispose
本身的类变量,那么应该实现Dispose来调用类变量上的Dispose
。 / p>
关于提供的代码:
if(RecordCollections!=null){
RecordCollections.Clear();
RecordCollections=null;
}
或者
RecordCollections = null;
由于这与清理托管内存有关,因此GC
执行主要工作并且不需要它,但是在我看来它是acceptable practice
,其中类变量显式无效,这使得用户改变每个分配,并且主要是尝试使用方法局部变量,直到除非状态需要在方法调用之间共享。对象分配滥用,可以更加严格控制。
就差异而言,虽然集合被明确清除然后无效或只是无效,但内存保持不变,直到调用点GC
,即un-deterministic
,但在我的查看它不是很清楚,如果一个对象被明确标记为{{GC
,那么null
如何显式地映射要收集的对象,这些对象不再可达,但对于各代,尤其是较高代的(升级对象)。 1}},然后GC可能需要花费更少/没有时间来跟踪根/引用,但是没有明确的文档来解释这个方面/实现。