处置对象异常

时间:2011-11-24 12:13:27

标签: c# idisposable objectdisposedexception

在浏览网页上的资源时,我遇到了很多boiletplate代码,它们看起来如下:

假设我们有一些public class CustomObject: IDisposable,它有很多方法。

现在,每个方法都有默认的健全性检查:

if (inputBuffer == null)
    throw new ArgumentNullException("inputBuffer");
if (outputBuffer == null)
    throw new ArgumentNullException("outputBuffer");
if (inputCount < 0)
    throw new ArgumentException("inputCount", "< 0");

但是(由于IDisposable接口实现),每个方法都会添加以下检查:

if (disposed)
    throw new ObjectDisposedException("MethodName");

现在 - 这是一种常见做法吗?我应该开始重新设计旧的一次性课程并实施这些检查吗?

3 个答案:

答案 0 :(得分:2)

  

现在 - 这是一种常见做法吗?

是的,建议。对于几乎所有成员。如果您的类是IDisposable,并且任何需要资源的方法在 Dispose()之后被称为,那么调用代码中会出现严重的逻辑错误。你的任务是发出信号。

但请注意,可能存在不严格依赖所拥有资源的方法(或属性),在Dispose()之后可以认为它们是安全的。例如IsOpen函数/属性。它可以简单地返回false,不需要例外。

但你应该将IsDisposed检查放入Dispose()iteself中,指导原则是多次调用Dispose()应该是安全的。

  

我应该开始重新设计旧的一次性课程并实施这些检查吗?

一般来说是一个好主意。是否值得付出努力取决于你。

答案 1 :(得分:1)

这取决于您的使用情况,如果有疑问,添加它不会有害。

对于打算由其他程序(例如库和框架)使用的类,我总是执行此检查并抛出正确的异常,因为这将有助于其他应用程序诊断错误并使类更加健壮。

对于仅供我的应用程序使用的内部类,您可以跳过检查,如果在调用方法时错误将很快出现。例如。如果类中的每个方法都使用了一个流,并且该流被处置或设置为null,则会很快导致异常。

如果内部类具有不会出错的方法,我将始终使用显式检查,因为我不希望某个方法在处理完对象后仍然有效(除了明确的方法)允许它,如IsDisposed)。

进行显式检查确实具有明确记录在处理对象后允许调用哪些方法的优点。更重要的是,如果您在不调用GuardDisposed的方法的顶部添加注释以声明它是允许的,那么任何不以GuardDisposed开头的方法或注释都可视为可疑

要实际执行检查,我更喜欢将其移动到单独的方法,并像断言一样使用它,例如

public class Foo
{
    private bool disposed;

    public void DoSomething ()
    {
        GuardDisposed ();
    }

    protected void GuardDisposed ()
    {
        if (disposed)
            throw new ObjectDisposedException (GetType ().Name);
    }
}

答案 2 :(得分:0)

你在Dispose()(通常是)方法中放入的代码,以确保它不会被明确地(和/或)在单个实例上显着地调用一次。

他们使用它,以防你在那个方法中执行一次可以执行的事情(DeleteFile,CloseTransaction ...)和你可能想到的任何其他操作,这不应该在你的应用程序域中执行两次。

所以,如果这是一种常见做法:我会说,这取决于您的应用程序要求。