在一个密封类实现了IDisposable(Implementing IDisposable on a

2019-08-05 20:15发布

我不认为这个问题已经被问过。 我有点困惑的最佳方式来实现IDisposable的密封类,具体而言,一个密封类,没有从基类继承。 (即,一个“纯密封类”,这是我的由术语。)

也许有些你同意我在执行这些准则IDisposable都非常混乱。 不过,我想知道,我打算实施方式IDisposable是足够的,安全的。

我做了一个分配部分的P / Invoke代码IntPtr通过Marshal.AllocHGlobal和自然,我要处理干净我创建的非托管内存。 所以我想的是这样的

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();
     }    
}

我假设,因为MemBlock是完全密封的,从来没有从实现另一个类派生的virtual protected Dispose(bool disposing)是没有必要的。

还有,就是终结严格必要吗? 所有的想法表示欢迎。

Answer 1:

终结是必要的,因为后备机制,最终免费非托管资源,如果你忘了打电话Dispose

不,你不应该声明virtual的方法sealed类。 它不会编译的。 此外,它不推荐申报新的protected的成员sealed类。



Answer 2:

A小调此外, 在一般情况下,一个常见的模式是有一个Dispose(bool disposing)的方法,让你知道你是在Dispose (其中更多的东西是可用的)VS终结(你真的不应该触及其他任何连接管理对象)。

例如:

 public void Dispose() { Dispose(true); }
 ~MemBlock() { Dispose(false); }
 void Dispose(bool disposing) { // would be protected virtual if not sealed 
     if(disposing) { // only run this logic when Dispose is called
         GC.SuppressFinalize(this);
         // and anything else that touches managed objects
     }
     if (ptr != IntPtr.Zero) {
          Marshal.FreeHGlobal(ptr);
          ptr = IntPtr.Zero;
     }
 }


Answer 3:

从乔·达菲的博客 :

对于密封类,这种模式不需要遵循,这意味着你应该简单地实现你的终结,并用简单的方法处置(即〜T()(最终确定)和Dispose()方法在C#)。 当选择了后者,你的代码仍然应该坚持以下关于实施定稿的指导方针和处理逻辑。

所以,是的,你应该是不错的。

你需要为迈赫达德提到的终结。 如果你想避免它,你可以看看的SafeHandle 。 我没有用的P / Invoke足够的经验,建议的正确用法。



Answer 4:

你不能声明在一个密封类的虚方法。 此外,在一个密封类声明protected成员给你一个编译器警告。 所以,你已经正确实现它。 从终结中调用GC.SuppressFinalize(这)是没有必要出于显而易见的原因,但不能伤害。

有一个终结与非托管资源打交道时是必不可少的,因为它们不会自动释放,你必须这样做,在终结与被该对象已被垃圾回收后自动调用。



文章来源: Implementing IDisposable on a sealed class
标签: c# pinvoke