当你的实现是一个空方法时,你如何"正确"实现Dispose()(根据FxCop)?(CA1063)

Cod*_*ike 15 .net c# fxcop idisposable

我有一个接口的实现,并且该接口扩展IDisposable.在我特定的接口实现中,我不需要处理任何东西,所以我只有一个空Dispose()方法.

public interface IMyStuff : IDisposable
{
}

public MyStuffImpl : IMyStuff
{
    public void Dispose()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

现在在FxCop中,这导致CA1063:

Error, Certainty 95, for ImplementIDisposableCorrectly
{
    Resolution   : "Provide an overridable implementation of Dispose(
                   bool) on 'MyStuffImpl' or mark the type as sealed. 
                   A call to Dispose(false) should only clean up native 
                   resources. A call to Dispose(true) should clean up 
                   both managed and native resources."
}
CriticalWarning, Certainty 75, for CallGCSuppressFinalizeCorrectly
{
    Resolution   : "Change 'MyStuffImpl.Dispose()' to call 'GC.SuppressFinalize(
                   object)'. This will prevent derived types that introduce 
                   a finalizer from needing to re-implement 'IDisposable' 
                   to call it."
}
Error, Certainty 95, for ImplementIDisposableCorrectly
{
    Resolution   : "Modify 'MyStuffImpl.Dispose()' so that it 
                   calls Dispose(true), then calls GC.SuppressFinalize 
                   on the current object instance ('this' or 'Me' in Visual 
                   Basic), and then returns."
}
Run Code Online (Sandbox Code Playgroud)

所以,看起来我可以通过以下两种方式解决此问题:


上课sealed:

public sealed MyStuffImpl : IMyStuff
{
    public void Dispose()
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

实现部分典型模式:

public MyStuffImpl : IMyStuff
{
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    private void Dispose(bool disposing)
    {
    }
}
Run Code Online (Sandbox Code Playgroud)

在我的情况下,我没有计划延长这个实现,所以我可能会通过制作它来解决它sealed,但我承认我不明白为什么它是重要的,如果它是密封的.

另外,仅仅因为我的班级已经密封,FxCop不再告诉我Dispose()应该打电话GC.SupressFinalize(this);但这是真的吗?无论如何总是在Dispose中调用SupressFinalize在.NET中"更好"吗?

SLa*_*aks 12

SuppressFinalize()除非你的实例有终结器,否则没有意义.
如果你的类没有终结器,但是没有sealed,你应该仍然SuppressFinalize,如果继承的类添加了终结器.

除了Dispose(bool)需要之外,您的两个选项都是正确的protected virtual.