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.
in a class, you should implement IDisposable and overwrite the Dispose method to allow you to control when the memory is freed. If not, this responsibility is left to the garbage collector to free the memory when the object containing the unmanaged resources is finalized.
Make sure that Dispose(bool) is declared as protected, virtual, and unsealed. Modify Dispose() so that it calls Dispose(true), then calls SuppressFinalize on the current object instance ( this , or Me in Visual Basic), and then returns. Modify your finalizer so that it calls Dispose(false) and then returns.
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.
A sealed class is abstract by itself, it cannot be instantiated directly and can have abstract members.
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.
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