【发布时间】:2011-03-09 02:48:44
【问题描述】:
在许多不同公司使用不同版本的 .NET 编写的许多遗留系统上工作,我一直在寻找以下模式的示例:
public void FooBar()
{
object foo = null;
object bar = null;
try
{
foo = new object();
bar = new object();
// Code which throws exception.
}
finally
{
// Destroying objects
foo = null;
bar = null;
}
}
对于任何了解 .NET 中内存管理如何工作的人来说,这种代码是非常不必要的。垃圾收集器不需要您手动分配null 来告诉旧对象可以被收集,分配null 也不会指示GC 立即收集该对象。
这种模式只是噪音,让人更难理解代码试图实现的目标。
那么,为什么我一直在寻找这种模式呢?有学校教授这种做法吗?是否有一种语言需要将 null 值分配给本地范围的变量才能正确管理内存?明确分配null 是否有一些我没有意识到的额外价值?
【问题讨论】:
-
来自一个不了解 C# 如何在超出范围时删除对事物的引用的人。
-
人们会停止为此责备 C++ 程序员吗?在 C++ 中,在这种情况下甚至不会进行堆分配,因此根本没有指针。此外,您还没有提供足够的代码来证明这是 C# 中的无操作。例如,您省略的代码可能会捕获闭包中的变量,该变量在函数返回后仍然存在(例如,通过订阅事件)。
-
@Ben Voigt:无论代码省略,
null的赋值都不会影响垃圾回收。他们的意图是“摧毁物体”,这是他们未能做到的。而且我也从未在 C++ 中做过这些事情。 -
有了这段代码,会有很大的不同:
Application.UnhandledException += { Frozzle( foo, bar ); }; -
@Ben Voigt:除非事件处理程序未注册,否则这些捕获的变量永远不会被 GC 处理。将本地引用分配给
null将仍然无效。foo和bar的值保持在捕获时的状态。
标签: c# .net design-patterns anti-patterns