建议49:在Dispose模式中应提取一个受保护的虚方法
2016-09-06 17:49
162 查看
建议49:在Dispose模式中应提取一个受保护的虚方法
在标准的Dispose模式中,真正的IDisposable接口的Dispose方法并没有做实际的清理工作,它其实是调用了下面的这个带bool参数且受保护的的虚方法:
之所以提供这样一个受保护的虚方法,是因为考虑了这个类型会被其他类型继承的情况。如果类型存在一个子类,子类也许会实现自己的Dispose模式。受保护的虚方法用来提醒子类:必须在自己的清理方法时注意到父类的清理工作,即子类需要在自己的释放方法中调用base.Dispose方法。
如果不为类提供这个受保护的虚方法,很有可能让开发者设计子类的时候忽略掉父类的清理工作。所以要在类型的Dispose模式中提供一个受保护的虚方法。
转自:《编写高质量代码改善C#程序的157个建议》陆敏技
在标准的Dispose模式中,真正的IDisposable接口的Dispose方法并没有做实际的清理工作,它其实是调用了下面的这个带bool参数且受保护的的虚方法:
/// <summary> /// 非密封类修饰用protected virtual /// 密封类修饰用private /// </summary> /// <param name="disposing"></param> protected virtual void Dispose(bool disposing) { //省略代码 }
之所以提供这样一个受保护的虚方法,是因为考虑了这个类型会被其他类型继承的情况。如果类型存在一个子类,子类也许会实现自己的Dispose模式。受保护的虚方法用来提醒子类:必须在自己的清理方法时注意到父类的清理工作,即子类需要在自己的释放方法中调用base.Dispose方法。
public class DerivedSampleClass : SampleClass { //子类的非托管资源 private IntPtr derivedNativeResource = Marshal.AllocHGlobal(100); //子类的托管资源 private AnotherResource derivedManagedResource = new AnotherResource(); //定义自己的是否释放的标识变量 private bool derivedDisposed = false; /// <summary> ///重写父类Dispose方法 /// </summary> /// <param name="disposing"></param> protected override void Dispose(bool disposing) { if (derivedDisposed) { return; } if (disposing) { // 清理托管资源 if (derivedManagedResource != null) { derivedManagedResource.Dispose(); derivedManagedResource = null; } } // 清理非托管资源 if (derivedNativeResource != IntPtr.Zero) { Marshal.FreeHGlobal(derivedNativeResource); derivedNativeResource = IntPtr.Zero; } //调用父类的清理代码 base.Dispose(disposing); //让类型知道自己已经被释放 derivedDisposed = true; } } public class SampleClass : IDisposable { //演示创建一个非托管资源 private IntPtr nativeResource = Marshal.AllocHGlobal(100); //演示创建一个托管资源 private AnotherResource managedResource = new AnotherResource(); private bool disposed = false; /// <summary> /// 实现IDisposable中的Dispose方法 /// </summary> public void Dispose() { //必须为true Dispose(true); //通知垃圾回收机制不再调用终结器(析构器) GC.SuppressFinalize(this); } /// <summary> /// 不是必要的,提供一个Close方法仅仅是为了更符合其他语言(如 /// C++)的规范 /// </summary> public void Close() { Dispose(); } /// <summary> /// 必须,防止程序员忘记了显式调用Dispose方法 /// </summary> ~SampleClass() { //必须为false Dispose(false); } /// <summary> /// 非密封类修饰用protected virtual /// 密封类修饰用private /// </summary> /// <param name="disposing"></param> protected virtual void Dispose(bool disposing) { if (disposed) { return; } if (disposing) { // 清理托管资源 if (managedResource != null) { managedResource.Dispose(); managedResource = null; } } // 清理非托管资源 if (nativeResource != IntPtr.Zero) { Marshal.FreeHGlobal(nativeResource); nativeResource = IntPtr.Zero; } //让类型知道自己已经被释放 disposed = true; } public void SamplePublicMethod() { if (disposed) { throw new ObjectDisposedException("SampleClass", "SampleClass is disposed"); } //省略 } } class AnotherResource : IDisposable { public void Dispose() { } }
如果不为类提供这个受保护的虚方法,很有可能让开发者设计子类的时候忽略掉父类的清理工作。所以要在类型的Dispose模式中提供一个受保护的虚方法。
转自:《编写高质量代码改善C#程序的157个建议》陆敏技
相关文章推荐
- 编写高质量代码改善C#程序的157个建议——建议49:在Dispose模式中应提取一个受保护的虚方法
- JavaSE8基础 同一个包下的子类,可以访问到父类中的 默认/受保护/公有方法
- 设计模式拾荒之备忘录模式(Memento Pattern): 一个需要注意方法权限的模式
- Dispose模式与Finalize, Dispose方法实现准则
- .net 使用提取模式使用SQL创建报表 出现“您请求的报表需要更多信息.”的解决方法
- 10_9_1编写代码,定义一个基类MyClass,其中包括虚礼方法GetString(),这个方法返回存储在受保护字段myString中的字符串,该字段可以通过只写公共属性ContainedStrin
- 安装Office时出现windows installer服务不能更新一个或多个受保护的windows文件错误的解决方法
- 一个简单的工厂方法模式
- JavaSE8基础 同一个包下的无关类 可以访问到 默认/受保护/公有方法
- 改善C#程序的建议4:C#中标准Dispose模式的实现
- Java 编写一个完美的equals()方法的建议
- 改善C#程序的建议4:C#中标准Dispose模式的实现
- 提取一个新方法
- 五分钟一个设计模式之工厂方法模式
- activity开启一个启动模式为SingleTask的activity,intent传递数据为空的解决方法
- 状态模式:分离对象的状态到各个独立类中,以避免一个方法体包含过多的判断
- 编写高质量代码改善C#程序的157个建议——建议50:在Dispose模式中应区别对待托管资源和非托管资源
- Visual Studio 连接 Mysql 实现一个选课管理系统--->提取数据的几种方法
- 一天一个设计模式---模板方法模式
- linux 不回车直接读取一个字符的方法(termios结构的描述了终端的模式,在这段代码中我们改变了它,使得终端能够接收到键盘输入马上返回。)