首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在密封类上实现IDisposable

在密封类上实现IDisposable
EN

Stack Overflow用户
提问于 2009-09-13 22:05:05
回答 4查看 10K关注 0票数 27

我不认为以前有人问过这个问题。我对在密封类上实现IDisposable的最佳方式有点困惑-具体地说,就是不从基类继承的密封类。(也就是说,“纯密封类”,这是我自编的术语。)

也许你们中的一些人同意我的观点,即实现IDisposable的指导方针非常令人困惑。也就是说,我想知道我打算实现IDisposable的方式是足够和安全的。

我正在做一些通过Marshal.AllocHGlobal分配IntPtr的P/Invoke代码,自然,我想干净地处理我创建的非托管内存。所以我在想像这样的东西

代码语言:javascript
复制
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)是不必要的。

另外,finalizer是否是严格必要的?欢迎所有的想法。

EN

回答 4

Stack Overflow用户

回答已采纳

发布于 2009-09-13 22:06:24

终结器是必要的后备机制,用于在忘记调用Dispose时最终释放非托管资源。

不,您不应该在sealed类中声明virtual方法。它根本不会编译。此外,不建议在sealed类中声明新的protected成员。

票数 15
EN

Stack Overflow用户

发布于 2009-09-13 22:16:33

一个小的补充;在一般的情况下,一个常见的模式是有一个Dispose(bool disposing)方法,这样你就可以知道你是在Dispose (在那里有更多的东西可用)还是在终结器(在那里你不应该真正接触任何其他连接的托管对象)。

例如:

代码语言:javascript
复制
 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;
     }
 }
票数 10
EN

Stack Overflow用户

发布于 2009-09-13 22:29:50

来自Joe Duffy's Weblog

对于密封的类,不需要遵循此模式,这意味着您只需实现终结器并使用简单的方法(即C#中的~T() (

)和Dispose() )进行处置。在选择后一种方法时,您的代码仍然应该遵循下面关于终结化和处置逻辑实现的指导原则。

所以,是的,你应该做得很好。

正如Mehrdad提到的,您确实需要终结器。如果你想避免它,你可以看看SafeHandle。我没有足够的P/Invoke经验来建议正确的用法。

票数 8
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/1418970

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档