博客
关于我
C#中Dispose和Close的区别!
阅读量:424 次
发布时间:2019-03-06

本文共 2849 字,大约阅读时间需要 9 分钟。

当我们开发C#代码的时候,经常碰到一个问题,有些class提供Close(),有些class提供Dispose(),那么Dispose和Close到底有什么区别?
首先,Dispose和Close基本上应该是一样的。Close是为了那些不熟悉Dispose的开发者设计的。因为基本上所有的developer都知道Close是干吗的(特别是对于那些有C++背景的developer)。
但是当我们写code时候,如果要实现Close和Dispose的时候,要注意Close和Dispose的设计模式。.net的一些class只提供Close,而且派生自IDisposable,并且隐藏了Dispose方法。是不是觉得很不明白了?
对这些class来说,关键在于它们显式的(explicitly)实现了IDisposable。对于隐式实现来说,你只需要调用"newA().Dispose()",但是对于显式实现来说,Dispose不会是这个class的成员函数。唯一的调用方式是你先要cast到IDisposable才行。(“new A().Dispose()”编译不过,但是“((IDisposable)newA()).Dispose()”可以编译过)。所以这样就符合了设计的要求:提供Close(),隐藏Dispose(),并且实现了IDisposable接口。
在.net的framework里,Close()被设计成public的,并且在Close()里面call被隐藏的Dispose();Dispose()去call另一个virtual的Dispose(bool)函数。所以如果你从这个class继承,你就必须实现Dispose(bool)方法。
调用者call Close()的时候就会call到你重载的那个Dispose(bool)方法去释放资源。
请参考

注意事项:
1,Close()不应该被定义成virtual。对于这个designpattern,Close()只是用来call那个隐藏的Dispose(),用户不应该改变Close的behavior。对于这个问题,System.IO.Stream也有设计问题。之所以有问题是为了满足向后兼容的需求。See
. 文档里面提到虽然Close()是virtual的,但是不应该被override。
演示代码如下:
 1 
using
 System;
 2 
 3 
namespace
 ConsoleApplication
 4 
{
 5 
    
abstract
 
class
 MyStream : IDisposable
 6 
    {
 7 
        
public
 MyStream()
 8 
        {
 9 
            m_unmanagedResource 
=
 Marshal.AllocCoTaskMem(
100
);
10 
            m_bitmap 
=
 
new
 Bitmap(
50
50
);
11 
        }
12 
13 
        
#region
 IDisposable Members
14 
        
void
 IDisposable.Dispose()
15 
        {
16 
            Dispose(
true
);
17 
            GC.SuppressFinalize(
this
);
18 
        }
19 
20 
        
protected
 
virtual
 
void
 Dispose(
bool
 isDisposing)
21 
        {
22 
            
if
 (
!
m_disposed)
23 
            {
24 
                
if
 (isDisposing)
25 
                {
26 
                    m_bitmap.Dispose();
27 
                }
28 
                Marshal.FreeCoTaskMem(m_unmanagedResource);
29 
                m_disposed 
=
 
true
;
30 
            }
31 
        }
32 
        
33 
        
public
 
void
 Close()
34 
        {
35 
            ((IDisposable)
this
).Dispose();
36 
        }
37 
38 
        
~
MyStream()
39 
        {
40 
            Dispose(
false
);            
41 
        }
42 
43 
        
private
 IntPtr m_unmanagedResource;     
//
 Unmanaged resource
44 
        
private
 Bitmap m_bitmap;                
//
 IDisposable managed resources
45 
        
private
 
bool
 m_disposed;
46 
        
47 
        
#endregion
48 
    }
49 
50 
    
class
 MyDerivedStream : MyStream
51 
    {
52 
        
public
 MyDerivedStream()
53 
        {
54 
            m_anotherMemory 
=
 Marshal.AllocCoTaskMem(
20
);
55 
            m_anotherImage 
=
 
new
 Bitmap(
24
24
);
56 
        }
57 
58 
        
protected
 
override
 
void
 Dispose(
bool
 isDisposing)
59 
        {
60 
            
if
 (
!
m_disposed)
61 
            {
62 
                
if
 (isDisposing)
63 
                {
64 
                    m_anotherImage.Dispose();
65 
                }
66 
67 
                Marshal.FreeCoTaskMem(m_anotherMemory);
68 
                
base
.Dispose(isDisposing);
69 
                m_disposed 
=
 
true
;
70 
            }
71 
        }
72 
73 
        
public
 
static
 
void
 Main(
string
[] args)
74 
        {
75 
            MyStream aStream 
=
 
new
 MyDerivedStream();
76 
77 
            aStream.Close();          
//
 Allowed
78 
            
//
 aStream.Dispose();    
//
 Cannot compile
79 
80 
            ((IDisposable)aStream).Dispose();     
//
 Allowed
81 
82 
            
//
83 
            
//
  This one works as well, because newStream calls the explicit implemented
84 
            
//
  IDisposable.Dispose method
85 
            
//
86 
            
using
 (MyStream newStream 
=
 
new
 MyDerivedStream())
87 
            {
88 
                
//
89 
                
//
  Do something
90 
                
//
91 
            }
92 
        }
93 
        
94 
        
private
 IntPtr m_anotherMemory;
95 
        
private
 Bitmap m_anotherImage;
96 
        
private
 
bool
 m_disposed;
97 
    }
98 
}
99 

转载地址:http://lzdyz.baihongyu.com/

你可能感兴趣的文章
C#获取Excel中所有的Sheet名称
查看>>
c#开发微信公众平台
查看>>
css实现背景渐变色效果
查看>>
unity3d由于Camera.main.transform报空引用错误的解决方案
查看>>
SQL Syscolumns
查看>>
jQuery实现日期字符串格式化
查看>>
vue学习笔记(十)路由
查看>>
[最全整理]关于决策树的一切
查看>>
100天搞定机器学习|Day9-12 支持向量机
查看>>
100天搞定机器学习|Day19-20 加州理工学院公开课:机器学习与数据挖掘
查看>>
100天搞定机器学习|Day22 机器为什么能学习?
查看>>
100天搞定机器学习|day37 无公式理解反向传播算法之精髓
查看>>
100天搞定机器学习|day38 反向传播算法推导
查看>>
《统计学习方法》极简笔记P2:感知机数学推导
查看>>
数据工程师必备的8项技能,不要只知道Python!
查看>>
R in action读书笔记(3)-第六章:基本图形
查看>>
R in action读书笔记(19)第十四章 主成分和因子分析
查看>>
CISC和RISC是什么?它们的特点和区别?
查看>>
选择排序 C++实现
查看>>
自定义UITableView各种函数
查看>>