Debug.Assert 与异常 [英] Debug.Assert vs Exceptions

查看:20
本文介绍了Debug.Assert 与异常的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

令人惊讶的是,我之前只能找到一个关于此主题的关于 SO 的问题,我只想让社区对我的方法进行信任投票"(或否!).

Surprisingly I was only able to find one previous question on SO about this subject, and I'd just like to get the community "Vote of Confidence" (or not!) on my approach.

我的看法是这样的:

  • 使用Debug.Assert 来说明您期望的情况.这将在我们完全控制我们的环境时使用,例如在一个方法中验证一些前置和后置条件.
  • 在出现异常情况时使用异常.处理外部资源,即文件、数据库、网络等是不费吹灰之力的.但是...
  • use Debug.Assert to state things you EXPECT would be true. This would be used when we are in complete control over our environment, for example in a method to verify some pre and post-conditions.
  • use Exceptions when exceptional circumstances arise. Dealing with external resources, i.e. files, databases, networks etc is a no-brainer. But...

在以下场景中它会变得有点模糊.请注意,这是一个人为的示例,仅用于说明!

It gets a little murky in the following scenario. Please note that this is a CONTRIVED EXAMPLE for illustration only!

假设我们有类 MyClass,它有一个公共属性 MyMode 和一个方法 GetSomeValueForCurrentMode().将 MyClass 视为打算在库中提供(发布构建)供其他开发人员使用的类.

Say we have class MyClass, which has a public property MyMode and a method GetSomeValueForCurrentMode(). Consider MyClass as one intended to be shipped (release built) in a library for use by other developers.

我们希望 MyMode 由此类的外部用户更新.现在,GetSomeValueForCurrentMode() 具有以下逻辑:

We expect MyMode to be updated by external users of this class. Now, GetSomeValueForCurrentMode() has the following logic:

switch(MyMode)
{
case Mode.ModeA:
return val1;
case Mode.ModeB:
return val2;
default:
//Uh-uh this should never happen

}

我在这里得到的是 MyClass 的用户让它处于无效状态.那我们该怎么办?

What I'm getting at here is that the user of MyClass has left it in an invalid state. So what should we do?

默认情况下,我们应该Debug.Assert 还是throw new InvalidOperationException(或其他)?

In the default, should we Debug.Assert or throw new InvalidOperationException (or other) ?

有一句口头禅说我们不应该相信我们班级的用户.如果我们选择 Debug.Assert 并将 MyClass 构建为发布版本(从而删除 Debug Asserts),则该类的用户将无法获得有用的信息,即他们将其置于无效状态.但这与其他口头禅有些相反,后者说只有在完全超出您控制范围的事情发生时才抛出异常.

There is one mantra that says we should not trust users of our classes. If we choose Debug.Assert and built MyClass as a release build (thereby removing the Debug Asserts) the user of the class wouldn't get helpful information that they had left it in an invalid state. But it's sort of contrary to the other mantra which says only throw exceptions when things completely out of your control happen.

我发现我对此进行了绕圈子 - 那些似乎没有明确正确"答案的编程辩论之一.所以让我们把它付诸表决!

I find I go round in circles with this - one of those programming debates that don't seem to have a definitive 'correct' answer. So let's put it to the vote!

我在一个相关的 SO 问题中注意到了这个回复(使用断言或例外的契约设计?):

I noticed this response in a related SO question (Design by contract using assertions or exceptions?):

经验法则是,您应该在尝试捕获自己的错误时使用断言,在尝试捕获其他人的错误时使用异常.换句话说,您应该使用异常来检查公共 API 函数的前提条件,以及每当您获得系统外部的任何数据时.您应该对系统内部的函数或数据使用断言.

The rule of thumb is that you should use assertions when you are trying to catch your own errors, and exceptions when trying to catch other people's errors. In other words, you should use exceptions to check the preconditions for the public API functions, and whenever you get any data that are external to your system. You should use asserts for the functions or data that are internal to your system.

对我来说,这是有道理的,并且可以与下面概述的断言然后抛出"技术结合使用.

To me, this makes sense, and can be coupled with the 'Assert then throw' technique outlined below.

欢迎提出想法!

推荐答案

我同意这里的大多数人的意见并遵循 Design-by-Contract.您应该尝试非常清楚地区分已部署代码中的需求(合同)和在设计期间弄清楚预期状态(调试断言).

I agree with most people here and follow Design-by-Contract. You should try and differentiate very clearly between requirements in deployed code (Contracts) and figuring out expected state during design (Debugging Assertions).

您应该始终将合同断言作为异常抛出(因为它们应该始终是异常的).大多数框架都内置了用于捕获调试断言的机制.但是在运行时你应该总是抛出异常.

You should ALWAYS throw contract assertions as exceptions (as they should always be exceptional). There are mechanisms built in to most frameworks for catching debug assertions. But at runtime you should always throw an exception.

我使用自定义库来帮助解决这个问题(在 C#/VB.NET 中).我最近把它放在 Codeplex (http://www.contractdriven.com/) 如果你是对这在实践中如何运作感兴趣.

I use a custom library to help with this (in C#/VB.NET). I recently put up it up on Codeplex (http://www.contractdriven.com/) if you're interested in how this works in practice.

这样做的一个附带好处是,当您开始更频繁地使用 DbC 时,您很少需要使用调试断言,因为已经在代码中写入了明确的保证,因此实际上很难进入无效状态.

A side benefit of this is that as you start using DbC more regularly, you seldom need to use debugging assertions as there are already explicit guarantees written in to your code, so it's actually difficult to get in to an invalid state.

所以你原帖中的问题......我在这里得到的是,MyClass 的用户让它处于无效状态.那么我们应该怎么做?"......永远不会出现.

So the question in your original post... "What I'm getting at here is that the user of MyClass has left it in an invalid state. So what should we do?"...should never arise.

您可能再也不需要调试任何东西了!;-)

You may never need to debug anything again! ;-)

这篇关于Debug.Assert 与异常的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆