false-positive:修复IDisposable的这种实现以符合dispose模式

Sha*_*lde 12 c# sonarqube

我的类实现IDisposable并遵循模式在哪里

public void Dispose()
{
    Dispose(true);
    GC.SuppressFinalize(this);
}
Run Code Online (Sandbox Code Playgroud)

但是声纳还在告诉我,我需要实施配置模式......

https://sonarqube.com/issues#issues=AVtsPLjmtpYg8Dj4z0MU

这是声纳的缺陷还是我错过了什么?

Val*_*Val 23

我看到你已经解决了这个问题,但是如果其他人遇到同样的问题,我会详细说明规则要求.

此规则的想法是允许潜在的派生类正确地处理类的成员.因此,如果您的类是密封的,该规则假定您的类正确处置自己并且什么都不做(还有另一个规则,S2931检查您的类是否包含IDisposable需要处理的字段).

如果类未密封,则规则检查它是否具有实现的基类IDisposable.如果它已经并且您的类也实现了IDisposable,那么规则将建议删除您的实现(例如IDisposable从类中删除接口)并覆盖基类的protected Dispose(bool)方法.

如果基类未实现IDisposable,则规则需要一个protected virtual Dispose(bool)方法(允许继承者正确地处理您的类).

如果您的类包含终结器,即析构函数,则规则检查其内容是否为单个调用Dispose(false).

规则检查Dispose()方法的内容(来自接口的内容)是否包含单个调用Dispose(true).如果您的班级有终结器,则该规则需要额外调用GC.SuppressFinalize(this).

基本上这些是IDisposable根据规则的正确实现:

密封类

public sealed class Foo1 : IDisposable
{
    public void Dispose()
    {
        // Cleanup
    }
}
Run Code Online (Sandbox Code Playgroud)

简单的实施

public class Foo2 : IDisposable
{
    public void Dispose()
    {
        Dispose(true);
    }

    protected virtual void Dispose(bool disposing)
    {
        // Cleanup
    }
}
Run Code Online (Sandbox Code Playgroud)

使用终结器实现

public class Foo3 : IDisposable
{
    public void Dispose()
    {
        Dispose(true);
        GC.SuppressFinalize(this);
    }

    protected virtual void Dispose(bool disposing)
    {
        // Cleanup
    }

    ~Foo3()
    {
        Dispose(false);
    }
}
Run Code Online (Sandbox Code Playgroud)

  • `GC.SuppressFinalize()`**必须永远**在没有密封的类的情况下,无论类本身是否具有终结器。如果派生类之一决定实现终结器,则没有合适的方法将其添加到派生类中。另请参阅https://docs.microsoft.com/zh-cn/dotnet/standard/design-guidelines/dispose-pattern#basic-dispose-pattern (3认同)
  • 是的,我们将更改说明. (2认同)
  • 对我来说,即使我正在实现“简单实现”,即像 Foo2 一样,我仍然收到警告。我更改为此处显示的“密封类”实现,以使警告消失 (2认同)