如何重新分配一次性对象变量?

时间:2011-09-28 23:18:55

标签: c# garbage-collection dispose idisposable

在C#中使用新对象重新分配一次性对象变量时,它在内存中是如何工作的?旧对象占用的内存空间是否会被新对象覆盖?或者我是否仍需要致电Dispose()以释放其使用的资源?

DisposableThing thing;

thing = new DisposableThing();
//....do stuff
//thing.Dispose();
thing = new DisposableThing();

3 个答案:

答案 0 :(得分:5)

在这种情况下,您有一个插槽/引用和一个IDisposable对象的实例。这两个实例都必须独立处理。编译器不会为IDisposable插入任何魔法。它只会将引用指向的实例更改为

一个好的模式将是以下

using (thing = new DisposableThing()) {
  // ... do stuff
}

thing = new DisposableThing();

理想情况下,thing的第二次使用也应在using块内完成

答案 1 :(得分:3)

它与任何其他作业相同: =不关心IDisposable或做任何魔术。

最初分配给变量的对象必须根据需要手动调用Dispose(或更好,using)。但是,此时调用Dispose可能并不总是正确的:谁拥有该对象并控制生命周期?

  

旧对象占用的内存空间是否会被新对象覆盖?

不适用。变量“名称”对象。 对象本身是,变量是变量 - 不是对象或“内存中的位置”。 (参见Eric Lippert的评论:前面是变量的高级视图,而Eric的评论更准确地反映了C#实现,精神和术语中的变量。)

变量只影响对象的生命周期,因为它们可以*保持一个对象不被回收(从而防止终结器[可能最终]运行)。但是,变量不控制对象语义生存期 - 即使不可回收,对象也可能被处置 - 或者无需根据需要调用Dispose

快乐的编码。


当处理超出简单范围的一次性对象时 - 对象可能在其生命周期内被分配给许多个不同的变量! - 我发现最好定义哪些“控制”,我在文档中注释。如果对象生命周期很好地限制在范围内,那么using效果很好。

*局部变量本身不一定足以保持对象强烈可达,因为如果稍后不在同一范围内使用变量/赋值,则可能会对其进行积极优化。这可能会困扰像计时器这样的物体。

答案 2 :(得分:1)

对于存在相同IDisposable对象的多个引用是可能的,也是常见的。覆盖或销毁除了其中一个引用之外的所有引用都没有错,前提是一个引用在它被销毁之前会调用Dispose。

请注意,IDisposable.Dispose的目的实际上并不是要销毁一个对象,而是让一个先前已经要求其他实体代表它做某事的对象(例如保留一个GDI句柄,授予一个专用的使用权限)。串口等),通知那些不再需要继续这样做的实体。如果没有任何东西告诉外部实体他们不再需要代表IDisposable对象继续做某事,他们就会继续这样做 - 即使他们所做的对象不再存在。