我的类实现了IDisposable
,并遵循模式
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
但是Sonar仍然告诉我需要实现dispose模式...
Sonar规则3881(IDisposable应该正确实现)
这是Sonar的缺陷还是我错过了什么?
我的类实现了IDisposable
,并遵循模式
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
但是Sonar仍然告诉我需要实现dispose模式...
Sonar规则3881(IDisposable应该正确实现)
这是Sonar的缺陷还是我错过了什么?
我看到您已经解决了问题,但是以防其他人遇到同样的问题,我将详细说明规则要求。
这个规则的想法是允许可能的派生类正确地处理您的类的成员。因此,如果您的类是密封的,该规则假定您的类正确地处置自己并且不会执行任何操作(还有另一个规则,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
}
}
简单实现
public class Foo2 : IDisposable
{
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
// Cleanup
}
}
使用终结器实现
public class Foo3 : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Cleanup
}
~Foo3()
{
Dispose(false);
}
}
GC.SuppressFinalize()
。如果派生类中的一个决定实现终结器,则没有合适的方法将其添加到派生类中。请参见https://learn.microsoft.com/en-us/dotnet/standard/design-guidelines/dispose-pattern#basic-dispose-pattern。 - bitbonk除非你的类实现了终结器,否则不要在你的Dispose()
方法中调用GC.SuppressFinalize()
。
GC.SuppressFinalize()
必须始终存在,详见我上面的评论。 - bitbonkSuppressFinalize
-继承者将是一个原因,如果稍后添加终结器,则可能会忘记添加它是另一个原因。 - Marek Feketevirtual
关键字:private bool disposed = false;
protected virtual void Dispose(bool disposing)
{
if (!disposed && disposing)
{
_dbContext.Dispose();
}
disposed = true;
}
SuppressFinalize
调用无效? - Marek Feketeprotected virtual void Dispose(bool disposing)
- Marek FeketeTrackedMethodStrategyManager.Dispose()
应该只包含对TrackedMethodStrategyManager.Dispose(true)
的调用,如果类包含终结器,则应调用GC.SuppressFinalize(this)
。 - Marek Fekete