C# 是否有任何理由在finally块中将对象设置为null?

C# 是否有任何理由在finally块中将对象设置为null?,c#,C#,我正在为我的公司清理一些C#代码,我注意到的一件事是,构建此应用程序的承包商一直将对象引用设置为null 例如: get { Object o = new Object(); // create a new object that is accessed by the reference 'o' try { // Do something with the object } finally { o = null; // set the reference to nu

我正在为我的公司清理一些C#代码,我注意到的一件事是,构建此应用程序的承包商一直将对象引用设置为null

例如:

get {
  Object o = new Object(); // create a new object that is accessed by the reference 'o'
  try {
   // Do something with the object
  }
  finally {
    o = null; // set the reference to null
  }
}
据我所知,创建的对象仍然存在。现在可能无法访问它,这取决于是否有任何其他引用,但它仍然存在,直到GC来清理它

有什么理由把这个放在最后一个街区吗?是否有任何情况下,这可能会造成一个在广告内存泄漏


谢谢

这取决于范围

在给定的示例中,
o
仅在属性的范围内定义。所以它将是无用的。但是,say
o
属于该类的范围。那么表示
o
的状态可能是有意义的


就目前而言,它是不需要的。

如果目的是让GC尽快收集对象,那么它是完全无用的

如果
o
引用的对象未在
try
块之后的任何位置使用,则在上次使用后(即变量
o
超出范围之前,以及在变量到达
finally
块之前),将立即选择该对象进行收集


另请参阅Lippert的相关说明。

我认为这样做至少有两个原因。首先,使用此模式有助于捕获因重用变量而导致的错误(即,如果这是较大代码序列的一部分,则变量名“o”可能在稍后的执行中包含不同的对象)。通过显式赋值null,如果以后尝试使用同一个对象,您将确保这样的代码会导致错误(例如,如果有较大的块,您意外地注释掉了构造函数)

其次,分配null确保对象可能可供GC收集。虽然对类变量更重要,但即使是局部变量也可能受益。由于分配未读取对象,因此任何现有优化都不应受到包括分配的影响(无论它多么不必要)。类似地,赋值本身可能会被完全优化掉(如果以后从未访问过对象),但由于这些优化都是编译器的权限,因此使用此结构允许早期收集不包含此类优化的替代编译模型

这需要比我更熟悉C#语言规范,但我怀疑它们没有规定必须在最后一次访问之后立即分配对象进行收集。当您尝试移植到一个不遵循相同原则的环境时,基于单个编译器或一组编译器的当前操作进行这种假设可能会导致以后的更多工作


至于潜在的内存泄漏,假设GC正常工作,并且该对象不需要特殊处理,那么应该没有问题——事实上,您正在专门删除对未使用内存的潜在引用,可能允许回收它。对于具有特殊处理要求的对象,我希望这些对象可以在同一个位置处理。

听起来像是前VB(经典)程序员,他们没有费心学习.NET内存管理与VBs COM管理的区别。我想这是一种很好的处理方法practice@MatiCicero:不,不是。这是一个典型的货运邪教节目,暴露出人们缺乏理解。埃里克·利珀特文章的链接为+1。重要的是要知道,C#中的“范围”概念与花括号的嵌套关系很小或根本没有关系。但是创建的对象无论如何都会占用内存,对吗?它只是对被设置为null的对象的引用。GC难道不知道对象最后一次使用的时间,因此不需要通过将其所有引用设置为null来明确告知对象吗?如果引用仍在范围内,则应将其设置为null,这就是GC知道它未被使用的原因。@Russell,啊,我认为GC的工作方式不同。我不知道你想说什么,因为它只是一堵文字墙。你可能想把你的答案分成几段。