CS.IDISP.DTOR
Provide a destructor (finalizer) when you implement IDisposable.
This rule identifies code that does not implement a finalizer (destructor) in a class that implements the Idisposable interface. Some classes implement the Idisposable interface to let the users free the resources allocated by the class. However, users might forget to call the Dispose method. To code defensively, ensure that such classes also implement a finalizer (destructor in C#, managed C++). This way, even if the user forgets to call the Dispose method, the resources get freed when the garbage collector calls the finalizer.
Vulnerability and risk
Not implementing standard design pattern will increase the risk of memory mis-management.
Mitigation and prevention
Problem is fixed by implementing Idisposable interface and calling Dispose() from the destructor.
Vulnerable code example
1 using System; 2 public class A : Idisposable 3 { 4 private bool _alreadyDisposed = false; 5 public A() 6 { 7 // resource allocated here 8 } 9 public virtual void Dispose() 10 { 11 Dispose(true); 12 } 13 public virtual void Dispose(bool isDisposing) 14 { 15 if (_alreadyDisposed) 16 { 17 return; 18 } 19 if (isDisposing) 20 { 21 // Free managed resources 22 } 23 // Free unmanaged resources 24 _alreadyDisposed = true; 25 } 26 // VIOLATION: Does not implement the destructor. 27 // However, Idisposable interface is implemented. 28 }
Fixed code example
1 // Problem is fixed by implementing Idisposable interface 2 // and calling Dispose() from the destructor. 3 Using System; 4 public class A : Idisposable 5 { 6 private bool _alreadyDisposed = false; 7 public A() 8 { 9 // resource allocated here 10 } 11 // FIXED: Destructor implemented. 12 // Also note the call to GC.SuppressFinalize(). 13 ~A() 14 { 15 // Dispose() called from the destructor 16 Dispose(false); 17 } 18 public virtual void Dispose() 19 { 20 Dispose(true); 21 GC.SuppressFinalize(); 22 } 23 public virtual void Dispose(bool isDisposing) 24 { 25 if (_alreadyDisposed) 26 { 27 return; 28 } 29 if (isDisposing) 30 { 31 // Free managed resources 32 } 33 // Free unmanaged resources 34 _alreadyDisposed = true; 35 } 36 }
REFERENCES: .NET Framework General Reference, Design Guidelines for Class Library Developers.