为什么在处理对象后需要将此变量设置为null?

noo*_*and 13 c# dispose

在PowerShell中的文档在这里中有如下有趣的评论:

PowerShell powershell = PowerShell.Create();

using (powershell)
{
    //...
}

// Even after disposing of the PowerShell object, we still 
// need to set the powershell variable to null so that the 
// garbage collector can clean it up.
powershell = null;
Run Code Online (Sandbox Code Playgroud)

处置后为什么powershell需要null设置?

Jus*_*gan 16

这不是直接的PowerShell问题.当using块终止时,指定的对象Dispose()调用其方法.这些通常会执行一些清理操作,通常是为了避免泄漏内存等等.但是,Dispose()不会删除该对象.如果对using块的引用仍然存在于块外(如本例所示),则对象本身仍在范围内.它不能被垃圾收集,因为它仍然有一个引用它,所以它仍然占用内存.

他们在你的例子中所做的就是删除该引用.当powershell设置为null时,它指向的PowerShell对象是孤立的,因为没有其他变量引用它.一旦垃圾收集器发现它,就可以释放内存.无论如何这都会发生在方法的最后(因为它powershell会超出范围),但这样你就可以更快地恢复系统资源.

(编辑:正如Brian Rasmussen指出的那样,.NET运行时对于垃圾收集非常聪明.一旦它到达powershell代码中的最后一个引用,运行时应该检测到你不再需要它并将其释放以进行垃圾收集.所以这powershell = null;条线实际上并没有做任何事情.)

顺便说一句,这个模式对我来说很奇怪.通常的方法是这样的:

using (PowerShell powershell = PowerShell.Create())
{
   //...
}
Run Code Online (Sandbox Code Playgroud)

这样,在它被处理之后powershell,在using块的末尾超出范围.更容易分辨变量的相关位置,并保存一些代码,因为您不再需要该powershell = null行.我甚至会说这是更好的编码实践,因为powershell从来没有存在于已处置状态.如果有人修改了您的原始代码并尝试powershellusing块外使用,那么无论发生什么都可能是坏事.

  • .NET运行时不需要您对引用进行空引用,并且只要不再引用它们就会检测到有资格进行收集的对象(即通常在方法结束之前发生). (6认同)

Nic*_*oiu 7

它不需要设置为null,它实际上不应该.即使您的代码没有为相应的变量赋值空值,.NET垃圾收集器也能够检测到特定指令后未使用的对象.(有关详细信息,请参阅http://blogs.msdn.com/b/cbrumme/archive/2003/04/19/51365.aspx.)至于为什么"官方"示例包含带有误导性评论的额外代码,甚至文档也可以有虫子......