我在这个和许多其他问题上的理念是“做有意义的事”。
在某些情况下,在类释放其资源后使用某些类成员可能是非常合理的。实际上,某些场景可能需要这样的使用。例如,如果一个对象通过网络连接管理异步事务,可能会要求它关闭,然后在它关闭之后,询问它已经处理了多少事务,是否有任何事务悬空等等。直到关闭完成后才能知道此类统计数据的值,从概念上讲,要求对象关闭然后向其询问与它已经完成的事情有关的历史信息在概念上没有错。
虽然有人可能会争辩说Close
应该关闭连接,同时允许使用报告历史信息的属性,而Dispose
应该关闭事物并禁止使用这些属性,但我认为这样的区别是没有帮助的。除其他外,人们可能希望连接释放与其关联的所有资源(Close
为了允许“重新打开”请求,可能会避免做某事)。Close
此外,在和之间的行为没有其他差异的情况下Dispose
,我认为没有必要纯粹要求两个单独的方法,这样Dispose
可以使统计数据无效。
从某种意义上说,许多IDisposable
对象可以被视为具有两部分——一个与外部资源交互的实体,以及一个与托管代码交互并且本身可能具有有限功能的实体。虽然“关注点分离”原则建议这两个部分应该是单独的对象(实际上,当这样的拆分可能会有所帮助时,会有一些尖齿),但在许多情况下,客户端代码会想要持有一个单一的引用,它可以服务于两个目的。该引用将必须实现IDisposable
,但处置不应破坏事物的托管代码方面。
例如,考虑 WinFormsFont
类。该类封装了两件事:(1) 关于字体(字体、大小、样式等)的信息集合,以及 (2) GDI 字体句柄。当 aFont
为Dispose
d 时,它不能再用于绘制文本,但它不会忘记字体、样式等。给定Dispose
d 字体,可以使用旧字体的信息构建新字体。不幸的是,大多数允许读取此类信息的属性都被 显式无效Dispose
,这意味着在许多情况下,如果想要生成一种类似于现有但已处理Font
但有一些更改的字体,则必须用从旧字体复制的信息构造一种新字体,基于该字体构造另一种新字体,然后Dispose
创建的第一个新字体。拥有一个保存与 typestyle 等相关的信息的类可能会有所帮助FontDescription
,以便在想要保存字体描述但不需要 GDI 句柄的情况下,字体描述可以存储在非-disposable 类,但这不是类的设计方式。