CS.IDISP.DISPOSE
Implement Dispose(bool) as a virtual method if IDisposable is implemented.
The standard design pattern to implement IDisposable interface is to implement both the Dispose() method and the finalizer(destructor). The code that is common to both these are factored out into a common method that is protected and virtual. The common method takes a parameter to indicate whether it is getting called from a Dispose() method or a finalizer.
Vulnerability and risk
When the code is duplicated, it is possible that a bug that gets fixed in one part is not fixed in the other.
Mitigation and prevention
Implementing the standard design makes it easier to understand the program and avoids potential bugs. When Dispose is implemented, there will invariably be code to free resources. This code will also be part of the finalizer. Therefore it makes sense to factor the common code out.
Vulnerable code example
// VIOLATION: This class does not implement the
// Dispose(bool) method that is called from both
// Dispose() and the destructor. The code for
// freeing resources is repeated in both Dispose()
// and the destructor.
using System;
public class A : IDisposable
{
public A()
{
// resource allocated here
}
~A()
{
// Free resources here
}
public virtual void Dispose()
{
// Free resources here.
GC.SuppressFinalize();
}
}
Fixed code example
// FIXED: The problem here is fixed by implementing the
// Dispose method that takes a bool paramter. Note that the
// method is called from both Dispose() and ~A.
using System;
public class A : IDisposable
{
private bool _alreadyDisposed = false;
public A()
{
// resource allocated here
}
~A()
{
// Dispose() called from the destructor
Dispose(false);
}
public virtual void Dispose()