Example implementation of IDisposable
public class MyResource : IDisposable
{
public MyResource(IntPtr handle)
{
this.handle = handle;
}
public void Dispose()
{
Dispose(disposing: true);
GC.SuppressFinalize(this);
}
protected virtual void Dispose(bool disposing)
{
if(!this.disposed)
{
if(disposing)
{
component.Dispose();
}
CloseHandle(handle);
handle = IntPtr.Zero;
disposed = true;
}
}
~MyResource()
{
Dispose(disposing: false);
}
}
MyResource object have pointer which is unmanaged. This is why this class should implement IDisposable interface. Implementation should be correct according to recommended pattern (see below for documentation).
There a re few points to highlight here:
IDisposableis meant to be used withusingkeyword.usingis callingIDisposable.Dispose method in the background- This method should be public then
protected Dispose(bool)method is meant to be called from finalizer via GCSuppressFinalizedisables this object from finalization mechanism in GC to prevent finalization code to be executed second time (see here)- Finalization is called from GC *only* if whoever is using this object will forget to use
usingor otherwise fail to callDisposemanually Disposemust be save to call multiple times (if(!this.disposed))Dispose(true)is meant to dispose also any other managed resources this implementation relies onDispose(false)is meant to be called from GC finalization mechanism. All managed resource are most likely already disposed so we cannot dispose them again
Further read:
https://learn.microsoft.com/en-us/dotnet/api/system.idisposable?view=net-6.0

