Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Implementing IDisposable on a sealed class

Tags:

c#

pinvoke

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.

like image 704
zebrabox Avatar asked Sep 13 '09 22:09

zebrabox


People also ask

When should you implement IDisposable?

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.

How do you implement IDisposable?

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.

How is IDisposable interface implemented?

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.

Can we instantiate sealed class?

A sealed class is abstract by itself, it cannot be instantiated directly and can have abstract members.


1 Answers

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.

like image 158
mmx Avatar answered Sep 21 '22 18:09

mmx