banana
欢迎访问香蕉部落http://www.bananatribe.net
DisposeClose基本上是一样的,Close是给不熟悉Dispose的开发者设计的;对于某些类来说,Close更有逻辑性.
.NET的一些class只提供Close,且派生自IDisposable并隐藏了Dispose方法; 这些class,它们其实显式的实现了IDisposable.
Close被设计成public,并且在Close里面显式实现了接口IDisposable中的Dispose方法; 而这个方法里面,又调用了方法Dispose(bool)(此为虚函数,使用protected修饰符),所以你从这些类(只提供Colse的类)中继承的话就必须实现Dispose(bool)这个方法;所以如果你要实现一个有Close的类的话,也需实现Dispose(bool);
        提示:编译器在编译析构函数时,会隐式的把析构函数编译为Finalize()方法的对应代码,确保执行父类的Finalize()方法.
1
//例1
abstract class SysClass : IDisposable
{
    
private IntPtr m_unmanagedResource;
    
private Bitmap m_bitmap;
    
private bool m_disposed = false;

    
public SysClass()
    
{
        m_unmanagedResource 
= Marshal.AllocCoTaskMem(100);
        m_bitmap 
= new Bitmap(50,50);
    }


    
void IDisposable.Dispose() //显式实现
    {
        Dispose(
true); //调用 Dispose(bool)
        GC.SuppressFinalize(this);
    }


    
//实现Dispose(bool),注意,此为虚函数,使用protected修饰符
    protected virtual void Dispose(bool isDisposing) 
    
{
        
if(!m_disposed)
        
{
            
if(isDisposing)
            
{
                
//在此处释放托管资源
                m_bitmap.Dispose(); //m_bitmap就是托管资源
            }

            
//在此处释放非托管资源
            Marshal.FreeCoTaskMem(m_unmanagedResource);
            m_disposed 
= true;
        }

    }


    
public void Close()
    
{
        ((IDisposable)
this).Dispose();
    }


    
~SysClass()
    
{
        Dispose(
false);
    }

}


class MyClass : SysClass //实现一个自己类里的Close
{
    
private IntPtr m_anotherMemory;
    
private Bitmap m_anotherImage;
    
private bool m_disposed = false;

    
public MyClass()
    
{
        m_anotherMemory 
= Marshal.AllocCoTaskMem(20);
        m_anotherImage 
= new Bitmap(25,25);
    }


    
//实现Dispose(bool)
    
//如果传入false,就只释放非托管资源;传入true,全部释放
    protected override void Dispose(bool isDisposing)
    
{
        
if(!m_disposed)
        
{
            
if(isDisposing)
            
{
                
//在此处释放托管资源
                m_anotherImage.Dispose();//m_anotherImage就是托管资源
            }

            
//在此处释放非托管资源
            Marshal.FreeCoTaskMem(m_anotherMemory);
            
base.Dispose(isDisposing);//子类会执行父类的构造函数,这里还需释放父类的
            m_disposed = true;
        }

    }

    
    
~MyClass()
    
{
        Dispose(
false);
    }

}


public static void Main(string[] args)
{
    SysClass sc 
= new MyClass();
    sc.Close(); 
//正确
    sc.Dispose(); //错误
    ((IDisposable)sc).Dispose(); //正确
}
MyClass类和它的父类都使用了双保险(Dispose+析构函数)来释放资源.如果用户调用了Dispose(),不会再调用析构函数(SuppressFinalize的缘故);但如果用户忘记调用Dispose(),就自然会转到析构函数而析构函数本来就具有释放托管资源的能力,所以只要将false传给Dispose就行了.
posted on 2007-08-16 09:46  香蕉部落blog  阅读(216)  评论(0编辑  收藏  举报

欢迎点击访问香蕉部落