我应该抛出当前方法还是让后面的方法抛出它
Should I throw in current method or let the later method throw it
在 好的 设计方面,我遇到了困难。
我不确定是应该让后面的方法抛出异常还是应该自己抛出异常。
事情是:
异常的类型根据被调用的方法而变化。在后一种方法中,它可能是 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.");
/* ... */
}
这是一个很容易完成的简单示例(没有意义)。
但当然,有些方法的评估要困难得多。
另一种选择是捕获异常并抛出一个新的正确类型。
但我想这会影响性能并在输出中记录一些不酷的东西。
一般来说,你应该总是尽可能快地投掷。通过这种方式,您可以防止代码在无效状态下执行,这可能会导致重大问题(f.e。您删除所有记录而不是一个记录,因为过滤器不正确)。
此外,如果您快速抛出消息,则可以确保调用者获得最有意义的消息。
public void Run(bool CanWaste)
{
if(!CanWaste)
throw new ArgumentException("CanWaste must be true", "CanWaste");
Waste();
// ...
}
但是,如果你不知道参数是否无效并且判断代价高昂(f.e。你需要执行它)然后让更深层次的方法抛出。
您可以在调用方法中处理 InvalidOperationException
:
public void Run(bool CanWaste)
{
_canWaste = CanWaste;
try
{
Waste();
}catch(InvalidOperationException ioe)
{
throw new ArgumentException("CanWaste must be true", "CanWaste", ioe);
}
}
当然在这种情况下很容易确定参数是否有效。这也不是最好的例子,因为 bool
参数只能是 true
没有多大意义。
不要抛出 或让代码抛出 不正确的类型异常,这对任何人都没有帮助。如果你得到一个无效的参数抛出 InvalidArgumentException
,否则让异常从库中冒泡到调用者。
根据描述,听起来 您正试图通过异常来控制执行流程。不要那样做。例外情况是 "Exceptions",当出现无法避免的异常情况时使用它们。
捕获并重新抛出该异常没有意义,除非您想重置堆栈跟踪您自己。
在 好的 设计方面,我遇到了困难。
我不确定是应该让后面的方法抛出异常还是应该自己抛出异常。
事情是:
异常的类型根据被调用的方法而变化。在后一种方法中,它可能是 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.");
/* ... */
}
这是一个很容易完成的简单示例(没有意义)。
但当然,有些方法的评估要困难得多。
另一种选择是捕获异常并抛出一个新的正确类型。
但我想这会影响性能并在输出中记录一些不酷的东西。
一般来说,你应该总是尽可能快地投掷。通过这种方式,您可以防止代码在无效状态下执行,这可能会导致重大问题(f.e。您删除所有记录而不是一个记录,因为过滤器不正确)。
此外,如果您快速抛出消息,则可以确保调用者获得最有意义的消息。
public void Run(bool CanWaste)
{
if(!CanWaste)
throw new ArgumentException("CanWaste must be true", "CanWaste");
Waste();
// ...
}
但是,如果你不知道参数是否无效并且判断代价高昂(f.e。你需要执行它)然后让更深层次的方法抛出。
您可以在调用方法中处理 InvalidOperationException
:
public void Run(bool CanWaste)
{
_canWaste = CanWaste;
try
{
Waste();
}catch(InvalidOperationException ioe)
{
throw new ArgumentException("CanWaste must be true", "CanWaste", ioe);
}
}
当然在这种情况下很容易确定参数是否有效。这也不是最好的例子,因为 bool
参数只能是 true
没有多大意义。
不要抛出 或让代码抛出 不正确的类型异常,这对任何人都没有帮助。如果你得到一个无效的参数抛出 InvalidArgumentException
,否则让异常从库中冒泡到调用者。
根据描述,听起来 您正试图通过异常来控制执行流程。不要那样做。例外情况是 "Exceptions",当出现无法避免的异常情况时使用它们。
捕获并重新抛出该异常没有意义,除非您想重置堆栈跟踪您自己。