• [转]C#中Dispose和Close的区别!


    原文地址: http://www.cnblogs.com/kevinwan/archive/2007/01/16/621869.html

    当我们开发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。对于隐式实现来说,你只需要调用"new A().Dispose()",但是对于显式实现来说,Dispose不会是这个class的成员函数。唯一的调用方式是你先要cast到 IDisposable才行。(“new A().Dispose()”编译不过,但是“((IDisposable)new A()).Dispose()”可以编译过)。所以这样就符合了设计的要求:提供Close(),隐藏Dispose(),并且实现了 IDisposable接口。

    在.net的framework里,Close()被设计成public的,并且在Close()里面call被隐藏的Dispose(); Dispose()去call另一个virtual的Dispose(bool)函数。所以如果你从这个class继承,你就必须实现Dispose (bool)方法。

    调用者call Close()的时候就会call到你重载的那个Dispose(bool)方法去释放资源。

    请参考 http://blogs.msdn.com/brada/archive/2003/07/06/50127.aspx 注意事项:
    1,Close()不应该被定义成virtual。对于这个design pattern,Close()只是用来call那个隐藏的Dispose(),用户不应该改变Close的behavior。对于这个问题, System.IO.Stream也有设计问题。之所以有问题是为了满足向后兼容的需求。See http://msdn2.microsoft.com/en-us/library/ms227422.aspx. 文档里面提到虽然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(5050);
    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(2424);
    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://yjmyzz.cnblogs.com
    本文版权归作者和博客园共有,欢迎转载,但未经作者同意必须保留此段声明,且在文章页面明显位置给出原文连接,否则保留追究法律责任的权利。
  • 相关阅读:
    大数据学习相关知识点
    SSMS登记密码清除
    ubuntu 18.04下安装Hadoop
    ubuntu 常见命令整理
    ubuntu 18.04下安装Java
    JQuery ajax请求返回(parsererror)异常处理
    (转载) C/C++编译和链接过程详解 (重定向表,导出符号表,未解决符号表)
    编译器的原理
    笔试题积累
    构造函数为什么不能声明为虚函数
  • 原文地址:https://www.cnblogs.com/yjmyzz/p/1097522.html
Copyright © 2020-2023  润新知