使用C#析构函数的示例

时间:2010-11-19 20:45:48

标签: c# garbage-collection destructor

我正在阅读C#中的析构函数,但我找不到合适的用例。

有人可以通过解释提供使用示例吗?

非常感谢。

更新
本书中的代码示例同时实现了Desctuctor和Dispose()方法,请参阅本书中的代码片段。

class MyClass
{
    bool disposed = false; // Disposal status
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }
    ~MyClass()
    {
        Dispose(false);
    }
    protected virtual void Dispose(bool disposing)
    {
        if (disposed == false)
        {
            if (disposing == true)
            {
                // Dispose the managed resources. Factored Dispose

            }
            // Dispose the unmanaged resources.

        }
        disposed = true;
    }
}

马尔科

6 个答案:

答案 0 :(得分:8)

现在很少需要终结者非常。当您可以直接访问本机资源时,使用是必需的 - 但现在您通常应该使用SafeHandle

乔·达菲有一个excellent post about this比我自己写的更详细 - 所以去读它:)

关于术语的快速说明:C#规范的ECMA版本将它们称为终结器;微软版本的规范总是将它们称为析构函数,并继续这样做。

答案 1 :(得分:2)

他们是终结者,而不是破坏者。它们通常用于清理非托管资源 - 如果您编写了自己的文件类,那么您需要使用终结器来清理本机文件句柄。

答案 2 :(得分:1)

C#中很少需要终结器,添加一个可能会导致垃圾收集器花费更长的时间来清理垃圾,因为运行终结器需要额外的传递。相反,您通常应该使用IDisposable模式。

终结器的一个示例用法是,如果您怀疑资源泄漏,可以在调试时使用它来检查在对象被垃圾回收之前是否已正确调用Dispose。如果一个持有非托管资源的对象在调用Dispose之前调用了终结器,则可能是资源泄漏的迹象。但由于终结器可能永远不会被调用,因此它不应包含任何应用程序关键逻辑。

答案 3 :(得分:1)

destructor你是什么意思? C#有

  • 您用于确定性销毁的IDisposable模式 当你不再需要它时,可以关闭Handles。所以他们现在关闭了,而不是每当GC决定收集可能更晚或根本没有的对象时。
    或者在纯托管代码中告诉对象将自己从对象图中删除,取消订阅事件,...
    通常与using语句
  • 一起使用
  • 终结者几乎没用。它运行在一个未知的时间,可能根本不运行,...
    我用它的唯一方法是提醒我,我忘了给某事件打电话 虽然它具有C ++析构函数的语法,但我认为它不等同于C ++析构函数。我更愿意将Dispose()视为析构函数。
  • 您用于原生资源的
  • Critical finalizationSafeHandles

我认为代替您发布的模式,现代代码应该拥有一个私有的SafeHandle,并在它自己的Dispose中调用它的Dispose方法。

答案 4 :(得分:0)

IDisposable接口提供了一种用作析构函数/终结器的方法。

我的意思是您可以实现IDisposable接口以释放对象正在使用的资源。正如其他人所说,这与一个好的旧析构函数不同,因为Dispose()方法不是由你自己直接调用,而是由托管代码在一段时间后处理你​​的对象。

答案 5 :(得分:0)

C#没有“析构函数”,因为你可能正在考虑它们。使用.NET的垃圾收集器,当您的类超出范围时,对象收集不会立即发生。

我认为你更感兴趣的是IDisposable模式。这是一种确定性的方法,可以清理对象使用的资源。

此外,.NET类可以具有“终结器”,这些“终结器”在收集对象时执行。如果你的对象的原始调用者忽略了它,它可以用来调用dispose。

但是,在类中实现终结器会将其排队等待GC的特殊处理,并可能会对性能产生影响。