【发布时间】:2012-08-29 22:39:05
【问题描述】:
.NET Framework 中的一个常见模式是 TryXXX 模式(我不知道他们是否真的这么称呼它),其中被调用的方法尝试做某事,如果成功则返回 True,或者False 如果操作失败。一个很好的例子是通用的Dictionary.TryGetValue 方法。
这些方法的文档说它们不会抛出异常:失败将在方法返回值中报告。到目前为止一切顺利。
我最近遇到了两种不同的情况,其中实现 TryXXX 模式的 .NET Framework 方法会引发异常。详情请见Bug in System.Random constructor? 和Uri.TryCreate throws UriFormatException?。
在这两种情况下,TryXXX 方法调用了引发意外异常的其他方法,并且这些异常已转义。我的问题:这是否违反了不引发异常的隐含合同?
换一种说法,如果你写TryFoo,你能保证异常不会逃逸吗,这样写?
public bool TryFoo(string param, out FooThing foo)
{
try
{
// do whatever
return true;
}
catch
{
foo = null;
return false;
}
}
这很诱人,因为这样可以保证不会逃脱任何异常,从而遵守隐含的合同。但它是一个 bug 隐藏器。
根据我的经验,我的直觉告诉我这是一个非常糟糕的主意。但是如果TryFoo 让一些异常逃逸,那么它真正的意思是,“我不会抛出任何我知道如何处理的异常”,然后合同的整个想法“我不会抛出异常”是扔出窗外。
那么,你的意见是什么? TryFoo 应该处理所有异常,还是只处理预期发生的异常?你的理由是什么?
【问题讨论】: