为何不同时使用Debug.Assert与异常抛出?
Debug.Assert 和参数校验异常:能不能同时用?
你说的没错,业内对这俩的分工早就达成共识:Debug.Assert 是用来抓程序员自己犯的逻辑错误(比如内部方法调用时传了不该传的null,属于代码写砸了),参数校验异常(比如ArgumentNullException)是用来拦截外部的非法输入(比如用户填的空字符串、其他组件传的无效值,属于不可控的外部意外)。
那到底能不能同时用?得看场景,不能一概而论:
可以同时用的场景:双重保障更稳妥
有些情况下,同时写确实有好处:
- 开发阶段,Assert会立刻触发中断,让你当场发现内部调用的问题(比如自己写的另一个方法调用这个函数时传了null),不用等程序跑异常抛出那一步,调试效率更高。
- 发布后,Debug.Assert会被自动编译掉(默认只在Debug模式生效),剩下的参数异常依然能死死守住程序入口,拦截外部的非法输入,避免程序崩溃或者产生脏数据。
没必要甚至冗余的情况
但很多时候,同时写纯属重复劳动,甚至会造成混淆:
- 如果你的方法是对外公开的API:参数校验异常已经足够。外部调用者不属于“自己人”,Assert对他们来说毫无意义,反而增加了代码量。
- 如果你的方法是内部私有方法:只用Assert就够了。内部调用都是自己团队写的代码,Assert触发就说明是逻辑bug,直接在开发阶段fix掉就行,发布后Assert被移除,也不需要额外的异常——毕竟内部调用都能传错,说明代码逻辑有大问题,不是靠异常能救的。
看你给的代码示例:别做重复校验
先给你修正下代码里的拼写错误:
void TestStringArg(string theStringArg) { Debug.Assert(theStringArg != null); Debug.Assert(theStringArg != string.Empty); ArgumentNullException.ThrowIfNull(theStringArg); ArgumentException.ThrowIfNullOrWhiteSpace(theStringArg); }
这里的问题很明显:ArgumentException.ThrowIfNullOrWhiteSpace已经包含了“null”“空字符串”“纯空白”的所有校验,前面的两个Assert和ArgumentNullException.ThrowIfNull全是重复逻辑,完全没必要分开写。
总结:按需选择,避免冗余
要不要同时用,核心看方法的定位:
- 对外公开方法:优先写参数校验异常,Assert可选(如果想在开发阶段抓内部调用的错误),但别重复校验。比如上面的例子,只需要保留
Debug.Assert(!string.IsNullOrWhiteSpace(theStringArg))和ArgumentException.ThrowIfNullOrWhiteSpace(theStringArg)就行。 - 内部私有方法:只用Assert,省得写重复代码。
- 特殊场景(既要内部调试快速报错,又要外部调用有异常保护):可以同时用,但一定要合并重复的校验逻辑,别写一堆冗余代码。
内容的提问来源于stack exchange,提问作者Avi
相关产品推荐
相关产品推荐

