何时检查此对象是否已被释放并抛出ObjectDisposedException是合理的

本文关键字:ObjectDisposedException 释放 检查 对象 是否 何时 | 更新日期: 2023-09-27 17:57:59

在实现IDisposable的类中,何时检查对象是否已被释放,如果已被释放则抛出ObjectDisposedException是合理的?在所有公共方法和属性中(Dispose除外)?有时从不

何时检查此对象是否已被释放并抛出ObjectDisposedException是合理的

您应该只在对已处理对象不起作用的方法中实现该检查。

例如:
如果您的类关闭了Dispose中的数据库连接或文件句柄,则所有需要这些数据库连接和文件句柄的方法都需要检查实例是否已公开。

如果一个对象支持IsDisposed,那么该方法本身永远不应该抛出;如果IsDisposed返回true,那么许多其他方法都可以抛出,但异常应该由这些方法生成,而不是由IsDispose生成。一个可能有一个实用方法AssertNotDisposed,如果对象被释放,它会抛出,但这种行为应该来自具有该名称的方法。

否则,我建议在许多情况下,让对象持有IDisposable对象,并能够在保持有用状态的同时处理内部对象是有用的。例如,一个对象的功能是显示和维护一个无模式对话框以从用户那里获取信息,即使在对话框关闭后,它也可以有效地保留字段内容的副本。这样的对象应该提供一个"关闭"方法,该方法将处理内部的一次性对象,但保持有用的状态。虽然它也可以有一个Dispose方法,它会调用Close,但也会设置一个"NoLongerValid"标志,导致字段属性抛出,我认为这不会真正增加任何值。

我承认,在许多情况下,一个对象在被处理后可以保持有用的状态,这表明一个类可能应该被拆分。例如,Font类可能应该分为一个非一次性的FontInfo类(包含字体的描述,但不包含GDI句柄)和一个IDisposable ReadyFont类(继承FontInfo并封装GDI字体对象)。使用字体的例程可以检查给定的对象是FontInfo还是ReadyFont;在前一种情况下,他们可以创建一个GDI字体,使用它,然后发布它;在后一种情况下,他们可以使用ReadyFont的GDI字体对象并释放它。ReadyFont创建者将负责确保其清理。

事实上,我不知道系统在呈现控件时是否会尝试使用与控件的Font属性相关联的GDI对象,但我知道如果Font已被释放(即使在将其分配给Font属性之前已被释放!),它也不会发出嘎嘎声。控件当然能够在必要时创建新的GDI字体;我不知道他们是总是创建一个新的GDI字体,还是只有在旧字体被丢弃的情况下才这样做。前一种行为似乎更具性能,但除非仔细编码,否则如果一个线程试图在另一个线程使用某个字体时处理该字体,则可能会导致问题。

唯一真正指定的是public void Dispose()本身不应该抛出任何东西。

任何需要(未)托管资源的方法都应该抛出。

在我看来,这只剩下几个有争议的案例:

  • IsOpen,IsDisposed:我不会扔
  • 其他IsSomeStatus:取决于情况
  • 长度,计数,位置:我不认为闭合流有长度,所以抛出

当类组合(不相关的)函数(如Stream和Collection)时,这会变得更加困难。我们不应该那样做。

使用已处理的对象是一个编程错误,您希望尽快找到它。

检查的地方越多,发现错误的速度就越快
您应该明确地检查它,在哪里,已处理的对象会导致其他类型的异常(即空指针),以避免混淆用户。

在其他地方,这取决于应用程序是否值得付出努力。

正如您所说,我将在除Dispose和IsDisposed之外的所有公共方法和属性中实现此检查。这是一种标准模式,可以防止开发人员在错误地认为类型仍然有效的情况下使用您的类型。

相关文章:
  • 没有找到相关文章