No creo que esta pregunta haya sido hecha antes. Estoy un poco confundido sobre la mejor manera de implementar IDisposable
en una clase sellada específicamente, una clase sellada que no hereda de una clase base. (Es decir, una "clase sellada pura" que es mi término inventado.)Implementación IDisposable en una clase sellada
Quizás algunos de ustedes estén de acuerdo conmigo en que las pautas para implementar IDisposable
son muy confusas. Dicho esto, quiero saber que la forma en que pretendo implementar IDisposable
es suficiente y segura.
Estoy haciendo un código P/Invoke que asigna un IntPtr
a través de Marshal.AllocHGlobal
y, naturalmente, quiero deshacerme limpiamente de la memoria no administrada que he creado. Así que estoy pensando en algo como esto
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();
}
}
Estoy asumiendo que ya MemBlock
y está completamente cerrado y nunca se deriva de otra clase que la implementación de un virtual protected Dispose(bool disposing)
no es necesario.
Además, ¿el finalizador es estrictamente necesario? Todos los pensamientos bienvenidos.
Pero, por supuesto, en el caso de que una clase sellada provenga de una clase base, entonces un Disposición virtual sería necesaria, ¿correcto? – zebrabox
También. El finalizador significa agregar a una cola de finalizador y tener la sobrecarga de efectivamente una doble recolección de basura. Parece una gran penalización pagar por usar recursos no administrados. ¿No hay forma de evitar el golpe de rendimiento? – zebrabox
En ese caso, 'anulará' el método. No puede declarar ningún método en una clase 'sealed' como' virtual'. Es un compilador ** error **. –