具有功能范围的变量

时间:2011-04-11 14:37:28

标签: c# exception-handling garbage-collection

如果抛出异常,CLR如何处理具有函数作用域的局部变量。 是否必须使用finally块,或者一旦流离开函数就处理变量

下面的

是一个小例子

    protected void FunctionX()
    {
        List<Employee> lstEmployees;
        try
        {
           lstEmployees= new List<Employee>();
           int s =  lstEmployees[1].ID; // code intended to throw exception
        }
        catch (Exception ex)
        {
            ManageException(ex, ShowMessage); //exception is thrown here
        }
        finally { lstEmployees= null; } // Is the finally block required to make sure the list is cleaned
    }

6 个答案:

答案 0 :(得分:3)

不要担心对象清理,这就是.NET和大多数现代语言在运行时提供垃圾收集功能的原因。

如果您的对象具有非托管资源的句柄,请执行该清理。

答案 1 :(得分:3)

要回答您的具体问题,请注意,不需要您列出的finally块。

null分配给引用变量实际上不执行任何操作,因为垃圾收集是非确定性的。作为一种简单的解释,垃圾收集器有时会检查堆中的对象以确定是否存在对它们的任何活动引用(这称为“rooted”)。如果没有活动引用,则这些引用符合垃圾回收的条件。

您的null作业不是必需的,因为一旦该函数退出,lstEmployees变量将超出范围,并且将不再被视为您在您的实例中创建的实例的有效引用try阻止。

某些类型(在.NET和第三方库中)实现IDisposable接口并通过Dispose()函数公开一些确定性清理过程。使用这些类型时,您应该始终在完成类型后调用Dispose()。如果实例的生命周期不应延伸到函数的生命周期之外,那么您可以使用using() { }块,但只有在类型实现IDisposable时才需要List<T> {{1}} 1}}(正如您在示例中所使用的那样)不会。

答案 2 :(得分:2)

其他一些答案在这里略有误导。

事实上,垃圾收集器(几乎)与变量lstEmployees无关。但永远不会需要设置为null,无论是在正常的代码流中还是在抛出异常之后。

设置对null的引用以释放它们指向的对象几乎永远不需要,尤其不适用于本地对象。

因此,垃圾收集器也不会关心异常。

另一方面,CG do 未处理的非托管资源总是需要手动清理(通过Dispose方法IDisposable 1}}接口)。为了确保在抛出异常后返回此类资源,您确实需要finally子句。或者,如果您不打算在本地处理异常,则可以用try … finally子句替换using

using (someUnmanagedResource) {
    // … use the resource …
}
// Will implicitly call someUnmanagedResource.Dispose() *whatever happens*!

答案 3 :(得分:0)

.NET语言是垃圾收集的,这意味着对象的生命周期会被跟踪,因此当垃圾收集找不到对象的引用时,垃圾收集将摆脱列表。

答案 4 :(得分:0)

完全没有。当变量超出范围时,垃圾收集器会处理它(当GC决定收集所有垃圾的时候......)

您唯一需要考虑的是,您可能不想等待GC完成其工作,因此释放了类实例的资源帮助(例如,假设您已在本地创建了一个实例这是对数据库连接的引用。连接将保持到GC负责删除实例,然后删除引用的连接,这可能需要一段时间。)

在这些情况下,请查看IDisposable界面,以便在GC删除实例之前主动释放资源。

答案 5 :(得分:0)

.NET的垃圾收集器将为您处理此问题。实际上,将“lastEmployees”设置为null可以完成与退出函数相同的操作。

根应用程序不再以某种形式或其他形式引用的任何项目都将标记为要收集。

在.NET中,您永远不必担心清理托管资源。因此,托管。

http://msdn.microsoft.com/en-us/library/0xy59wtx.aspx