如何仅在引发异常时处理对象

本文关键字:处理 对象 异常 何仅 | 更新日期: 2023-09-27 18:10:49

我在构造函数中实例化了一个一次性对象(在我的例子中是FileStream(,需要对它做一些工作。然而,这可能会引发许多不同的异常。现在,我甚至不想过多地处理这些异常,而是希望允许它们传播到调用者。但是,我需要先处理对象。现在最好的方法是什么?现在我只能想到这样的东西:

IDisposable disposableObject = InstantiateDisposable();
bool error = false;
try
{
    DoWork(disposableObject);
}
catch (ReallyBadException e)
{
    error = true;
    throw new EvenWorseException("some message", e);
}
catch (Exception)
{
    error = true;
    throw;
}
finally
{
    if (error) disposableObject.Dispose();
}

这是正确的吗?或者在某些特殊情况下会跳过Dispose((吗?有更简单的方法吗?如果你出于任何原因需要单独捕获一堆不同的异常,并且你总是必须复制&粘贴该error = true;位。

编辑:只是澄清一下:我只需要在DoWork()失败/抛出异常的情况下处理对象。如果这个方法成功了,我现在还不想处理这个对象,因为以后会有更多的工作要做

为什么不反转逻辑?

IDisposable disposableObject = InstantiateDisposable();
bool error = true;
try
{
    DoWork(disposableObject);
    error = false; // if it gets to this line, no exception was thrown
}
catch (ReallyBadException e)
{        
    throw new EvenWorseException("some message", e);
}    
finally
{
    if (error) disposableObject.Dispose();
}

如何仅在引发异常时处理对象

不要试图"处理"你实际上什么都做不了的异常。

除非你从记录诊断中得到了一些明确的有用性,或者作为不同类型重新抛出,否则就让它失败吧;释放finally子句中的disposableObject!

当涉及到异常处理时,许多人会感到太困惑,或者做一些毫无意义的恶作剧。当它从底部出来时,你应该得到一个痕迹。catch&立即重新投掷。

IDisposable disposableObject = InstantiateDisposable();
bool error = true;
try {
    DoWork(disposableObject);
    error = false; // if it gets to this line, no exception was thrown
} finally {
    if (error) disposableObject.Dispose();
}

希望这能有所帮助!

IDisposable disposable = InstantiateDisposable();
try
{
    try
    {
        DoWork(disposable);
    }
    catch (Exception)
    {
        disposable.Dispose();
        throw;
    }
}
catch (ReallyBadException ex)
{
    throw new EvenWorseException("some message", ex);
}

尽管,实际上,除非您要返回对象或将其保存起来,否则您应该使用using块并始终处理它。

为什么catch中没有Dispose

IDisposable disposableObject = InstantiateDisposable();
try
{
    DoWork(disposableObject);
}
catch (ReallyBadException e)
{
    disposableObject.Dispose();
    throw new EvenWorseException("some message", e);
}
catch (Exception)
{
    disposableObject.Dispose();
    throw;
}

在这样的实用程序对象中包装如何?

class Disposer : IDisposable
{
    private IDisposable target;
    public Disposer(IDisposable target)
    {
        this.target = target;
    }
    public void Cancel()
    {
        this.target = null;
    }
    public void Dispose()
    {
        this.target?.Dispose();
        Cancel();
    }
}

这相当于管理bool error标志,但如果您喜欢using:,可以说会更干净一些

IDisposable disposableObject = InstantiateDisposable();
using (Disposer disposer = new Disposer(disposableObject))
{
    try
    {
        DoWork(disposableObject);
        disposer.Cancel();
    }
    catch (ReallyBadException e)
    {
        throw new EvenWorseException("some message", e);
    }
}
// ... continue with disposableObject

在没有错误的情况下不处理对象是有原因的吗?你可能应该是!

使用标准的using模式意味着您的对象将始终被安全地处理,然后您只需要担心捕获任何需要特别注意的异常(例如ReallyBadException(。任何其他异常都将由调用者决定。

using (IDisposable disposableObject = InstantiateDisposable())
{
    try
    {
        DoWork(disposableObject);
    }
    catch (ReallyBadException e)
    {
        throw new EvenWorseException("some message", e);
    }
}