• C#中Dispose和Close的区别


    此篇文章是转载的,出处:http://www.xici.net/b713781/d47980278.htm

    当我们开发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.

        注,本文译自我们team manager Richard Wong的精彩讲解,贴于此处以期望能够对大家有所帮助。感谢Richard!

    演示代码如下:

     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 
  • 相关阅读:
    初学c课程笔记整理7-->>二维数组、字符串、指针
    初学c课程笔记整理6-->>数组
    ipad上自定义view的旋转适配
    苹果mac电脑中brew的安装使用及卸载详细教程
    Apple、Google、Microsoft的用户体验设计原则
    iOS图片拉伸技巧
    子网掩码解析【转载】
    Ios8,Xcode6下 设置Launch Image 启动图片
    ios8 设置单元格分割线无效
    简述UIScrollView的属性和用法
  • 原文地址:https://www.cnblogs.com/ssqjd/p/1386433.html
Copyright © 2020-2023  润新知