如何仅在引发异常时处理对象
本文关键字:处理 对象 异常 何仅 | 更新日期: 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);
}
}