My class implements IDisposable
and follows the pattern where
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
But sonar is still telling me I need to implement the dispose pattern...
https://sonarqube.com/issues#issues=AVtsPLjmtpYg8Dj4z0MU
Is this a defect with sonar or have I missed something?
Implement the dispose pattern A Dispose(bool) method that performs the actual cleanup. Either a class derived from SafeHandle that wraps your unmanaged resource (recommended), or an override to the Object. Finalize method. The SafeHandle class provides a finalizer, so you do not have to write one yourself.
If an object doesn't implement IDisposable , then you don't have to dispose of it. An object will only expose Dispose if it needs to be disposed of.
The Dispose method is automatically called when a using statement is used. All the objects that can implement the IDisposable interface can implement the using statement. You can use the ildasm.exe tool to check how the Dispose method is called internally when you use a using statement.
Typically, types that use unmanaged resources implement the IDisposable or IAsyncDisposable interface to allow the unmanaged resources to be reclaimed. When you finish using an object that implements IDisposable, you call the object's Dispose or DisposeAsync implementation to explicitly perform cleanup.
I saw that you already fixed the issue, but in case someone else has the same problem, I will elaborate on the rule requirements.
The idea of this rule is to allow potential derived classes to correctly dispose the members of your class. Hence if your class is sealed, the rule assumes your class correctly disposes itself and does nothing (there is another rule, S2931 which checks if your class contains IDisposable
fields that need to be disposed).
If the class is not sealed, the rule checks if it has a base class that implements IDisposable
. If it has and your class also implements IDisposable
, the rule will recommend to remove your implementation (e.g. remove the IDisposable
interface from your class) and override the base class's protected Dispose(bool)
method.
If the base class does not implement IDisposable
, the rule requires a protected virtual Dispose(bool)
method (to allow the inheritors to correctly dispose your class).
If your class contains a finalizer, i.e. destructor, the rule checks if its content is a single invocation of Dispose(false)
.
The rule checks if the content of the Dispose()
method (the one from the interface) contains a single invocation of Dispose(true)
. If your class has a finalizer, the rule requires an additional call to GC.SuppressFinalize(this)
.
Basically these are the correct implementations of IDisposable
according to the rule:
Sealed class
public sealed class Foo1 : IDisposable
{
public void Dispose()
{
// Cleanup
}
}
Simple implementation
public class Foo2 : IDisposable
{
public void Dispose()
{
Dispose(true);
}
protected virtual void Dispose(bool disposing)
{
// Cleanup
}
}
Implementation with a finalizer
public class Foo3 : IDisposable
{
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
// Cleanup
}
~Foo3()
{
Dispose(false);
}
}
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With