如何正确实现IDisposable接口

本文详细介绍了.NET中IDisposable接口的实现方法,包括Dispose模式、析构函数及Close方法的使用,帮助开发者正确管理非托管资源。

摘要生成于 C知道 ,由 DeepSeek-R1 满血版支持, 前往体验 >

   如果一个对象拥有非托管资源,则应该实现IDisposable接口,这样调用方可以在使用之后及时释放资源。
   有很多关于.Net的书籍和文章都描述了如何实现IDisposable接口,但是几乎每一篇实现的都不完全一样,这里将几个主要的实现进行合并,试图找出能够适应绝大多数条件的实现方法。
   
   实现代码
   
 1None.gifnamespace Disposable
 2ExpandedBlockStart.gifContractedBlock.gifdot.gif{
 3InBlock.gif    public class ResourceBase:IDisposable
 4ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
 5InBlock.gif        private bool disposed = false;
 6InBlock.gif
 7InBlock.gif        ~ResourceBase()
 8ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
 9InBlock.gif            Dispose(false);
10ExpandedSubBlockEnd.gif        }

11InBlock.gif
12InBlock.gif        protected virtual void Dispose(bool disposing)
13ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
14InBlock.gif            if (disposed)
15InBlock.gif                return;
16InBlock.gif            //多线程环境
17InBlock.gif            lock (this)
18ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
19InBlock.gif                if (disposing)
20ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
21InBlock.gif                    //release managed resource
22ExpandedSubBlockEnd.gif                }

23InBlock.gif                //release unmanaged resource;
24InBlock.gif                disposed = true;
25ExpandedSubBlockEnd.gif            }

26ExpandedSubBlockEnd.gif        }

27InBlock.gif        public void Close()
28ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
29InBlock.gif            Dispose();
30ExpandedSubBlockEnd.gif        }

31InBlock.gif
32ContractedSubBlock.gifExpandedSubBlockStart.gif        IDisposable Members#region IDisposable Members
33InBlock.gif
34InBlock.gif        public void Dispose()
35ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
36InBlock.gif            Dispose(true);
37InBlock.gif            GC.SuppressFinalize(this);
38ExpandedSubBlockEnd.gif        }

39InBlock.gif
40ExpandedSubBlockEnd.gif        #endregion

41ExpandedSubBlockEnd.gif    }

42InBlock.gifpublic class Resource:ResourceBase
43ExpandedSubBlockStart.gifContractedSubBlock.gif    dot.gif{
44InBlock.gif        private bool disposed = false;
45InBlock.gif        protected override void Dispose(bool disposing)
46ExpandedSubBlockStart.gifContractedSubBlock.gif        dot.gif{
47InBlock.gif            if (disposed)
48InBlock.gif                return;
49InBlock.gif            //多线程环境
50InBlock.gif            lock (this)
51ExpandedSubBlockStart.gifContractedSubBlock.gif            dot.gif{
52InBlock.gif                try
53ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
54InBlock.gif                    if (disposing)
55ExpandedSubBlockStart.gifContractedSubBlock.gif                    dot.gif{
56InBlock.gif                        //release managed resource
57ExpandedSubBlockEnd.gif                    }

58InBlock.gif                    //release unmanaged resource
59InBlock.gif                    
60ExpandedSubBlockEnd.gif                }

61InBlock.gif                finally
62ExpandedSubBlockStart.gifContractedSubBlock.gif                dot.gif{
63InBlock.gif                    base.Dispose(disposing);
64InBlock.gif                    disposed = true;
65ExpandedSubBlockEnd.gif                }

66InBlock.gif
67ExpandedSubBlockEnd.gif            }

68InBlock.gif            
69ExpandedSubBlockEnd.gif        }

70ExpandedSubBlockEnd.gif    }

71ExpandedBlockEnd.gif}
   
   分析
   Dispose()方法用于显式的释放资源,可以在代码中直接调用,或者使用using语句间接调用。GC.SuppressFinalize告诉GC在垃圾回收时,不需要调用析构函数,可以提高垃圾回收的效率。
   Close()方法与Dispose()作用相同,只是为了适应某些有Open方法的类,Open/Close相互对应比较符合一般习惯。
   析构函数用于在垃圾回收的时候释放资源。如果用户没有/忘记在使用之后释放资源,CLR会在垃圾回收的时候调用此函数。虽然资源较晚被释放,但总是好于不释放。
   Dispose(bool)是真正释放资源的地方,参数disposing表明是用户主动释放资源还是在垃圾回收时释放。当用户主动释放资源时,由于此对象的成员中,某些托管资源持有非托管资源,因此需要释放这些托管资源,如果这些托管资源实现了IDisposable,调用Dispose()即可。在垃圾回收时,由于无法确定这些托管资源是否已经被回收了,因此不要试图释放托管资源,GC会释放这些资源的。如果多次调用Dispose(bool)会有副作用,则需要添加disposed变量来判断是否已经释放了资源。如果对象可能会在多线程环境中使用,需要加锁防止同步问题。
   最后,如果该类有派生类的话,要在派生类中override父类的Dispose(bool)方法,并在释放资源后调用父类的Dispose(bool),以正确释放父类的资源。

转载于:https://www.cnblogs.com/wangyh/archive/2007/04/17/717015.html

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值