我在良好的设计方面遇到了困难
我不确定是否应该让以后的方法抛出异常,或者我是否应该自己抛出它。
事情是:
异常的类型根据被调用的方法而变化。在后面的方法中,它可能是InvalidOperation,但在当前方法中,ArgumentException可能更适合。
现在我应该真正执行所有检查以抛出正确类型的异常,还是应该让更深层次的方法抛出错误类型的异常?
考虑一下:
private bool _canWaste = false;
/// <summary>
/// Runs around and wastes something.
/// </summary>
/// <exception cref="InvalidOperationException">
/// Thrown when <paramref name="CanPower"/> is false.
/// </exception>
public void Run(bool CanWaste) {
_canWaste = CanWaste;
// <- Should I check if we can waste and throw an ArgumentException here or
// throw the 'wrong' type later in Waste?
Waste();
}
/// <summary>
/// Wastes something.
/// </summary>
/// <exception cref="InvalidOperationException">
/// Thrown when we cannot waste.
/// </exception>
private void Waste() {
if(!_canWaste) throw new InvalidOperationException("We cannot waste.");
/* ... */
}
这是一个简单的例子(没有意义),它很容易完成。
但是,当然,有些方法的评估要困难得多。
另一个选择是捕获异常并抛出一个新的正确类型。
但我想这会影响性能并在输出中记录一些不冷却的东西。
答案 0 :(得分:3)
不要抛出或让代码抛出不正确的类型异常,这对任何一个都没有帮助。如果你得到一个无效的参数抛出InvalidArgumentException
,否则让异常从库中冒泡到调用者。
从描述中,听起来 您试图通过异常控制执行流程。不要那样做。例外情况是&#34;异常&#34;,当有特殊情况无法避免时使用它们。
除非你想自己重置堆栈跟踪 ,否则捕获并重新抛出该异常是没有意义的。
答案 1 :(得分:2)
一般情况下,你应该尽可能快地扔掉。在这种情况下,您可以防止代码在无效状态下执行,这可能会导致重大问题(例如,您删除所有记录而不是一个,因为过滤器不正确)。
此外,如果您快速投掷,请确保调用者获得最有意义的消息。
public void Run(bool CanWaste)
{
if(!CanWaste)
throw new ArgumentException("CanWaste must be true", "CanWaste");
Waste();
// ...
}
但是,如果您不知道参数是否无效且确定是否昂贵(例如,您需要执行它),那么让更深层次的方法抛出。
您可以在调用方法中处理InvalidOperationException
:
public void Run(bool CanWaste)
{
_canWaste = CanWaste;
try
{
Waste();
}catch(InvalidOperationException ioe)
{
throw new ArgumentException("CanWaste must be true", "CanWaste", ioe);
}
}
当然,在这种情况下,很容易确定参数是否有效。它也不是最好的例子,因为bool
参数只能true
没有多大意义。