泛型类中的析构函数

时间:2014-05-07 14:32:05

标签: c# destructor

我创建了一个通用的DAO工厂。工厂类实现IDisposable。

我想为这个泛型类创建一个析构函数,以便它正确实现IDisposable。

如何为此泛型类定义析构函数?是否有必要或者我应该将IDispoable和析构函数的实现留给其非泛型基类?

1 个答案:

答案 0 :(得分:1)

有关MCSD认证工具包(考试70-483)第193页的一些关键词:

析构函数≈(它几乎等于)base.Finalize(),析构函数被转换为Finalize方法的覆盖版本,该方法执行析构函数的代码然后调用基础class的Finalize方法。然后,它完全不确定,你能够知道什么时候被调用,因为它取决于GC。

如果某个类不包含托管资源且没有非托管资源,则不需要 实现IDisposableor有一个析构函数。

如果该类只有托管资源,它应该实现IDisposable,但它不会 需要一个析构函数。 (当析构函数执行时,您仍然无法确定托管对象 存在,所以无论如何你都不能称他们的Dispose方法。)

如果该类只有非托管资源,则需要实现IDisposable并需要 程序不调用Dispose时的析构函数。

Dispose方法必须安全才能运行多次。你可以通过使用a来实现 变量以跟踪它之前是否已经运行过。

Dispose方法应该释放托管和非托管资源

析构函数应该只释放非托管资源。 (当析构函数执行时,你 无法确定托管对象是否仍然存在,因此无论如何都无法调用他们的Dispose方法。)

释放资源后,析构函数应调用GC.SuppressFinalize ,因此对象可以 跳过终结队列。

具有非托管和托管资源的类的实现示例:

using System;

class DisposableClass : IDisposable
{
    // A name to keep track of the object.
    public string Name = "";

    // Free managed and unmanaged resources.
    public void Dispose()
    {

        FreeResources(true);
    }

    // Destructor to clean up unmanaged resources
    // but not managed resources.
    ~DisposableClass()
    {
        FreeResources(false);
    }

    // Keep track if whether resources are already freed.
    private bool ResourcesAreFreed = false;

    // Free resources.
    private void FreeResources(bool freeManagedResources)
    {
        Console.WriteLine(Name + ": FreeResources");
        if (!ResourcesAreFreed)
        {
            // Dispose of managed resources if appropriate.
            if (freeManagedResources)
            {
                // Dispose of managed resources here.
                Console.WriteLine(Name + ": Dispose of managed resources");
            }

            // Dispose of unmanaged resources here.
            Console.WriteLine(Name + ": Dispose of unmanaged resources");

            // Remember that we have disposed of resources.
            ResourcesAreFreed = true;

            // We don't need the destructor because
            // our resources are already freed.
            GC.SuppressFinalize(this);
        }
    }
}