如果我的对象从未构造过,为什么要调用Dispose
本文关键字:为什么 调用 Dispose 对象 我的 如果 | 更新日期: 2023-09-27 18:22:12
基于这篇文章,我在Windows窗体的组件和IDisposable对象之间创建了一个桥梁。它看起来像这样:
namespace MyApp
{
public class Disposer: Component
{
private readonly Action<bool> _dispose;
public Disposer(Action<bool> disposeCallback)
{
if (disposeCallback == null)
throw new ArgumentNullException(nameof(disposeCallback));
this._dispose = disposeCallback;
}
protected override void Dispose(bool disposing)
{
this._dispose(disposing);
base.Dispose(disposing);
}
}
}
到目前为止还不错。然后我创建了单元测试,其中包括一个用于构造函数参数的特定验证的单元测试。
[TestMethod]
[ExpectedException(typeof(ArgumentNullException))]
public void Disposer_ShouldNotAllowNullActions()
{
new Disposer(null);
}
问题是:不仅我的测试失败了,而且它实际上被中止了。测试平台本身崩溃(ReSharper测试运行程序)。通过深入查看我的Windows事件查看器,我可以看到Dispose()方法正在被调用,由于this._dispose
在这一点上基本上为null,它会以NullReferenceException
失败。
我通过提供一个空lambda作为默认值来解决这个问题。
但是,如果构造函数抛出异常(我已经确认了),为什么要调用Dispose
方法呢?
Component
类必须有一个调用this.Dispose()
的终结器,这会导致调用您的覆盖。
即使构造函数没有完成,终结器也会运行——这允许清理构造函数失败之前分配的所有资源。
为什么要调用
Dispose
方法?
即使构造函数抛出异常,也会调用类的终结器。Component
的终结器调用Dispose()
:
~Component() {
Dispose(false);
}
由于您重写了Dispose(bool)
,因此如果构造函数抛出异常,就会调用您的重写。由于这在您的代码中是真实的可能性,我建议确保this
和this._dispose
都不为空。