在.Net中的函数/方法中声明和处理局部变量

时间:2014-02-04 20:41:08

标签: c# garbage-collection

直到最近,我还没有真正困扰过如何最好地声明和处理一个局部变量,但我想我会一劳永逸地问一下并得到一些反馈,因为它现在开始越来越多地让我感到烦恼。 / p>

创建创建本地对象的函数/方法时,最好创建和处理对象的方法。

为简单起见,假设被调用对象的方法永远不会产生异常,即ConvertThisToString

private string myFirstFunction()
{
  MyDataType myObject = null;
  try
  {
    myObject = new MyDataType();
    return myOjbect.ConvertThisToString();
  }
  finally
  {
    myObject = null;
  }
 }

private string mySecondFunction()
{
  MyDataType myObject = new MyDataType();
  return myOjbect.ConvertThisToString();
}

这两个函数是否正常,它只是关于编码首选项还是有一种方法比另一种方法更好?为什么呢?

我的观点是,为了使对象无效,总是需要try / catch,这可能是为了无效而使用try / catch的过度杀戮,而另一种方法不会调用任何明确的方法来销毁对象,这可能是依赖于.NET GC从内存中释放它。

我应该使用“using”语句吗?

嗯,这可能是一个不正确的陈述。离开某个功能时是否会立即销毁和处理本地对象,或者GC管理层或其他人在以后将其清除。

感谢您的反馈。

亨利

更新:

删除了catch块,因为它在我的问题中引起了混乱。自从我说过之后,本来应该没有出现在那里,不会发生任何错误。

5 个答案:

答案 0 :(得分:4)

那是非常错误的。

  • 不要吞下例外。

  • 在其范围的末尾将变量分配给null根本无助于GC。


如果你的对象实际上有昂贵的资源,它应该实现IDisposable(正确!),你应该使用using语句来处理它(但只有当你完成它时! )

答案 1 :(得分:2)

您无需指定为null。当对象离开作用域时,它将自动符合GC的条件。没有必要做任何特别的事情。

基本上,只需编写第二个简单版本。

  

我应该使用“using”语句吗?

如果你的对象正在包装资源(不是通过new ...分配的内存,而是本机资源)并实现IDisposable,那么是的,你应该使用using语句来保证那些被清理起来。

  

当离开某个功能时,本地对象是否会立即被销毁和处理,或者是由GC管理层或其他人在以后清除它。

将收集合格。在未来的某个时刻,GC会清理它,但这种情况发生的时间不确定。

答案 2 :(得分:0)

这里最好的方法是Using语句。

类似的东西:

private string myFirstFunction()
{
  using(MyDataType myObject = new MyDataType())
  {
     return myObject.ConvertThisToString();
  }

}

这将在执行后处理对象。

答案 3 :(得分:0)

您不需要使用try / catch / finally将变量设置为null。当方法以自己的时间结束时,.NET GC将清除所有未引用的类。

如果您正在做一些非常密集的事情(比示例节目更多),那么您可以将变量引用设置为null作为指向GC的指针,不再引用它。如果您正在做一些最终标记Gen2集合的变量引用然后您做更多的事情阻止GC收集您的变量(因为范围尚未保留 - 在这种情况下,这只会对您的程序产生影响)方法)。 这是一个极端的例子,因为.NET GC旨在从日常关注中删除这方面的编程,无论如何,当范围结束时它应该被清除 - 它可能会更长一点。

如果引用的对象实现了IDisposable,则使用'using',并且通常这样做是为了释放非托管资源 - 尽管可能还有其他原因导致类实现此接口。

你的第一种方法是完全矫枉过正......它应该只是如MySecondFunction()中描述的那样,并且不要像那样吞下异常(我指的是空的catch块) - 因为它会导致错误,无法管理的代码! :)

答案 4 :(得分:0)

与几乎所有内容一样,这完全取决于您使用的是什么对象。如果您正在创建的对象实现IDisposable,那么您最好放在使用中(通常)。除此之外,大多数对象将被垃圾收集器清理干净。如果您是访问COM对象的类的生产者,那么作为生产者,您应该提供一个适当的清理,例如实现IDisposable接口并正确处理Dispose()。正如其他人评论吞咽异常甚至尝试/捕捉每种方法似乎不是一个合理或好主意。如果您正在进行的调用有可能抛出异常并且您有未管理或泄漏的对象,那么您应该通过try / finally或using(再次,如果适用)来处理。