想象一下,在C#(在.NET 4.5.x中)中,在实现using
的对象周围有IDisposible
块。想象一下
将两个异常传递给全局错误处理程序的最佳方法是什么?
代码示例:
class SampleClass : IDisposable
{
void doSomething()
{
// Imagine that this code is actually doing something
// Except that it unexpectedly hits an exception
throw new Exception("Exception A");
}
void Dispose()
{
// Imagine that this code is doing some cleanup
// Except that it is buggy
// And throws more exceptions
throw new Exception("Exception B");
}
}
static void Main()
{
try
{
using(var c = new SampleClass())
{
c.doSomething();
}
}
catch (Exception e)
{
// Code that records and reports exceptions
RecordException(e);
}
}
在上面的示例中,我希望记录Exception A
和Exception B
的所有详细信息。将两个例外传递给RecordException
的最佳方法是什么?
This article建议SafeUsingBlock
分机。这是既定的最佳做法吗?
修改:在这种情况下我控制并可以重写SampleClass
和SampleClass.Dispose()
答案 0 :(得分:1)
如果你控制了Dispose()
方法,我建议不惜一切代价使其防错。通常,您应该能够安全地依赖IDisposable
s Dispose()
。
如果这是一个你无法控制的课程,你的try
包裹using
的建议会起作用,但为了使它更优雅,我可能会做更接近的事情:
try
{
var c = new SampleClass();
c.doSomething();
c.Dispose();
}
catch(Exception e)
{
RecordException(e);
}
SafeUsingBlock()
看起来已经完成了工作,但我不认为这是最佳实践:这是一种解决方法。已确立的最佳做法是使Dispose()
方法安全。
此外,如果SampleClass
是您无法控制的,请考虑将其包装在也实现IDisposable
的façade中,并处理Dispose()
方法中的错误,例如
public class SampleClassWrapper : IDisposable
{
private readonly SampleClass _target;
public SampleClassWrapper(SampleClass target)
{
_target = target;
}
public void doSomething()
{
_target.doSomething();
}
public void Dispose()
{
try
{
_target.Dispose();
}
catch(Exception e)
{
RecordException(e);
}
}
}
然后,您可以安全地在SampleClassWrapper
区块内使用using
,而无需担心Dispose()