我为我的代码使用默认的IDisposable实现模板(模式)。

片段:

public void Dispose()
{
    Dispose(true);

    GC.SuppressFinalize(this);
}

protected virtual void Dispose(bool isDisposing)
{
    if (!this.disposed)
    {
        if (isDisposing)
        {
            //cleanup managed resources
        }

        //cleanup unmanaged resources

        this.disposed = true;
    }
}

我的问题:为什么呼叫“GC.SuppressFinalize(this)”在Dispose公共方法?我会放置“GC.SuppressFinalize(this)”。在“if(isDisposing)”中处理受管资源后受保护方法的一部分。

像这样:

protected virtual void Dispose(bool isDisposing)
{
    if (!this.disposed)
    {
       if (isDisposing)
       {
           //cleanup managed resources

           GC.SuppressFinalize(this);
       }

       //cleanup unmanaged resources

       this.disposed = true;
    }
}
有帮助吗?

解决方案

我认为它是模板设计模式的明显案例。

您的抽象类旨在处理所需的所有重要/必要任务(此处为GC.SuppressFinalize(this)),并允许派生类仅覆盖代码的某些部分。

这里有2个案例:
在Dispose中,Snippet 1,SuppressFinalize Snippet 2,SuppressFinalize,Dispose(true)

这里,Snippet 1确保始终执行GC.SuppressFinalize。在代码片段2中,GC.SuppressFinalize的执行受派生类的支配。

因此,通过在Dispose方法中放置GC.SuppressFinalize,您作为类的设计者将始终确保无论派生类编写的代码是什么,都将执行GC.SuppressFinalize。

这只是在Dispose中编写SuppressFinalize而不是Dispose(true)的好处。

其他提示

Dispose(bool isDisposing)方法不属于 IDisposable 界面。

您通常会从 Dispose(true) =“noreferrer”> Dispose 方法,并从终结器中调用 Dispose(false),作为对象尚未被删除的情况下的后备地布置。

致电 SuppressFinalize 告诉GC,不需要调用对象的终结器,大概是因为在调用 Dispose 时完成了所有清理工作。

如果您的班级没有终结器,那么您根本不需要调用 SuppressFinalize ,因为没有终结器可以抑制!

Joe Duffy有一些很棒的处理,定稿,垃圾收集等指南

我认为可以选择任一种布局,但可能他们想强调“将所有解除分配代码放入此方法中”。在受保护的Dispose方法中,所以他们将其他工件(抑制终结)放在别处。

另外,假设一个派生类有另一个原因来调用受保护的Dispose方法,但是仍然希望完成最终化(出于任何想象的原因,我不知道)。

原因.Dispose是当托管代码(您的代码)处置对象从而选择退出完成时。人们通常会通过终结者创建另一条进入Dispose(bool处理)的路线,并且该调用对于终结者来说没有任何意义。

这个想法是你的清理代码只应该被调用一次。但是有两个入口点: Dispose 方法和对象终结器。当调用 Dispose 时,您选择退出最终化,以便只调用一次清理代码。 此处的代码可能会更好地说明这一点。

引用:

// NOTE: Leave out the finalizer altogether if this class doesn't 
// own unmanaged resources itself, but leave the other methods
// exactly as they are. 
许可以下: CC-BY-SA归因
不隶属于 StackOverflow
scroll top