I don't think this question has been asked before. I'm a bit confused on the best way to implement IDisposable
on a sealed class—specifically, a sealed class that does not inherit from a base class. (That is, a "pure sealed class" which is my made up term.)
Perhaps some of you agree with me in that the guidelines for implementing IDisposable
are very confusing. That said, I want to know that the way I intend to implement IDisposable
is sufficient and safe.
I'm doing some P/Invoke code that allocates an IntPtr
through Marshal.AllocHGlobal
and naturally, I want to cleanly dispose of the unmanaged memory I've created. So I'm thinking of something like this
using System.Runtime.InteropServices;
[StructLayout(LayoutKind.Sequential)]
public sealed class MemBlock : IDisposable
{
IntPtr ptr;
int length;
MemBlock(int size)
{
ptr = Marshal.AllocHGlobal(size);
length = size;
}
public void Dispose()
{
if (ptr != IntPtr.Zero)
{
Marshal.FreeHGlobal(ptr);
ptr = IntPtr.Zero;
GC.SuppressFinalize(this);
}
}
~MemBlock()
{
Dispose();
}
}
I'm assuming that because MemBlock
is completely sealed and never derives from another class that implementing a virtual protected Dispose(bool disposing)
is not necessary.
Also, is the finalizer strictly necessary? All thoughts welcome.
The finalizer is necessary as a fallback mechanism to eventually free unmanaged resources if you forgot to call Dispose
.
No, you shouldn't declare a virtual
method in a sealed
class. It wouldn't compile at all. Also, it's not recommended to declare new protected
members in sealed
classes.