令人惊讶的是,我只能找到关于这个主题的一个关于 SO 的先前问题,我只想让社区对我的方法进行“信任投票”(或不投票!)。
我的看法是这样的:
- 用来
Debug.Assert
陈述你期望是真的事情。这将在我们完全控制我们的环境时使用,例如在验证某些前置条件和后置条件的方法中。 - 出现异常情况时使用异常。处理外部资源,即文件、数据库、网络等是轻而易举的事。但...
在以下场景中它变得有点模糊。请注意,这是一个人为的示例,仅用于说明!
假设我们有一个 MyClass 类,它有一个公共属性 MyMode 和一个方法GetSomeValueForCurrentMode()
。将 MyClass 视为一个打算在库中交付(发布构建)以供其他开发人员使用的类。
我们希望 MyMode 由此类的外部用户更新。现在,GetSomeValueForCurrentMode()
有以下逻辑:
switch(MyMode)
{
case Mode.ModeA:
return val1;
case Mode.ModeB:
return val2;
default:
//Uh-uh this should never happen
}
我在这里得到的是 MyClass 的用户已将其置于无效状态。那么我们应该怎么做呢?
默认情况下,我们应该Debug.Assert
还是throw new InvalidOperationException
(或其他)?
有一个口头禅说我们不应该信任我们课程的用户。如果我们选择 Debug.Assert 并将 MyClass 构建为发布版本(从而删除 Debug Asserts),则该类的用户将不会获得他们将其置于无效状态的有用信息。但这有点与另一个口头禅相反,后者说只有在完全无法控制的事情发生时才抛出异常。
我发现我在这个圈子里转了一圈 - 那些似乎没有明确的“正确”答案的编程辩论之一。所以让我们把它付诸表决吧!
编辑:我在一个相关的 SO 问题中注意到了这个响应(使用断言或异常进行合同设计?):
经验法则是,当你试图捕捉自己的错误时,你应该使用断言,而当你试图捕捉别人的错误时,你应该使用异常。换句话说,您应该使用异常来检查公共 API 函数的先决条件,以及每当您获得系统外部的任何数据时。您应该对系统内部的功能或数据使用断言。
对我来说,这是有道理的,并且可以与下面概述的“断言然后抛出”技术相结合。
欢迎提出想法!