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

本文关键字:对象 变量 一次性 分配 何重新 | 更新日期: 2023-09-27 18:09:55

在c#中,当用新对象重新分配一次性对象变量时,它如何在内存中工作?旧对象占用的内存空间会被新对象覆盖吗?还是我仍然需要调用Dispose()来释放它所使用的资源?

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

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

在本例中,您有一个槽/引用和两个IDisposable对象实例。这两个实例必须独立处理。编译器没有为IDisposable插入任何魔法。它只会将实例的引用点更改为

一个好的模式是这样的

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

理想情况下,thing的第二次使用也应该在using块内进行

它的工作原理与任何其他赋值相同: =不关心IDisposable或做任何魔术。

初始分配给变量的对象必须根据需要手动调用Dispose(或者更好的是,使用using)。然而,在这一点上调用Dispose可能并不总是正确的:谁拥有对象并控制生命周期?

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

不适用。变量"name"对象。对象本身就是,变量就是变量——而不是对象或"内存中的位置"。(参见下面Eric Lippert的注释:前面是变量的高级视图,而Eric的注释更准确地反映了c#实现、精神和术语中的变量。)

变量仅影响对象的生存期,因为它们可以*阻止对象被回收(从而阻止终结器[可能最终]运行)。然而,变量不控制对象语义生存期——对象即使在不可回收的情况下也可能被dispose——或者不需要根据需要调用Dispose

幸福的编码。


当处理超出简单作用域的一次性对象时——对象可能在其生命周期内被赋值给许多不同的变量!—我发现最好定义谁"控制",我在文档中注释。如果对象的生存期很好地限制在一个范围内,那么using就可以很好地工作。

*局部变量本身不一定足以保持对象强可达,因为如果以后不在同一作用域中使用变量/赋值,则可能会被积极优化。这可能会困扰定时器等对象。

对同一个IDisposable对象存在多个引用是可能的,也是常见的。重写或销毁除其中一个引用外的所有引用都没有问题,只要其中一个引用在销毁之前调用了Dispose。

注意idisable的目的。Dispose实际上并不是销毁一个对象,而是让一个对象之前请求其他实体代表它做一些事情(例如保留一个GDI句柄,授予一个串行端口的独占使用等),通知那些实体它们不再需要继续这样做。如果没有任何东西告诉外部实体它们不再需要代表IDisposable对象继续做某事,它们将继续这样做——即使它们正在为之做的对象不再存在。