【发布时间】:2017-04-24 13:04:20
【问题描述】:
我已经阅读了一些内容,试图弄清楚何时适当地使用断言和异常,但总体上我仍然缺少一些东西。可能我只是需要更多的经验,所以我想举一些简单的例子来更好地理解在什么情况下我应该使用什么。
示例 1:让我们从无效值的经典情况开始。例如,我有以下类,其中两个字段都必须为正:
class Rectangle{
private int height;
private int length;
public int Height{
get => height;
set{
//avoid to put negative heights
}
}
//same thing for length
}
请注意,在这个例子中我不是在谈论如何处理用户输入,因为我可以为此创建一个简单的控制流。虽然,我面临这样的想法,即在其他地方可能存在一些意外错误,我希望检测到这一点,因为我不想要具有无效值的对象。所以我可以:
- 使用
Debug.Assert并在发生这种情况时停止程序,以便在出现错误时更正可能的错误。 - 扔
ArgumentOutOfRangeException基本上做同样的事情?这感觉不对,所以只有当我知道我要在某个地方处理它时才应该使用它。不过,如果我知道在哪里处理异常,我不应该解决它所在的问题吗? 或者它可能是针对可能发生的事情,但 您无法直接在代码中进行控制,比如用户输入(可以处理,无一例外,但也许其他东西不能)或加载数据?
问题:我理解断言和异常的含义了吗?另外,您能否举一个示例,在该示例中处理 异常可能有用(因为在发生之前您无法控制的事情)?除了我提到的案例之外,我无法弄清楚还会发生什么,但我显然仍然缺乏经验。
扩展一下我的问题:我可以想到引发异常的多种原因,例如NullReferenceException、IndexOutOfBoundsException、DirectoryNotFoundException 或 FileNotFoundException 等 IO 异常。虽然,我除了简单地停止程序(在这种情况下,不应该使用断言吗?)或给出问题发生位置的简单消息之外,无法弄清楚处理它们变得有用的情况。我知道即使这很有用,异常也意味着对“错误”进行分类并为如何修复它们提供线索。不过,一个简单的信息真的对它们有用吗? 这听起来很可疑,所以我会坚持“我从来没有遇到过合适的情况,因为经验”的口头禅。
示例 2:现在让我们谈谈用户输入,使用第一个示例。正如我所预料的那样,我不会使用异常来检查值是否为正,因为这是一个简单的控制流。但是如果用户输入一个字母会发生什么?我应该在这里处理一个异常(可能是一个简单的ArgumentException)并在catch 块中给出一条消息吗?或者也可以通过控制流来避免(检查输入是否为int 类型或类似的类型)?
感谢任何能解决我挥之不去的疑问的人。
【问题讨论】:
-
没有一个正确的答案,这完全取决于您拥有的支持系统来处理您的代码的客户端程序员出错并且不知道为什么。输入无效数据的用户也不例外。
-
我知道这在很大程度上取决于情况,我只是想弄清楚可能会出现什么样的情况。另外,坚持这个简单的例子,相反,如果我的意思是验证值只是为了检测代码中的错误,我应该使用
Debug.Assert。如果我打算实现保存/加载数据并且加载的文件中的某些内容可能会失败,我可以捕获它并使用“数据损坏”消息停止程序。这种推理是否正确,或者我没有得到断言和/或异常的目的? -
这是一个不完整的问题。通过鼓励(或强迫)他们输入正确的数据来与用户打交道。当程序可能只是帮助用户时停止程序似乎没有必要
-
加载的文件更复杂,因为您无法控制源。
-
这主要是一种意见/情况。如果这是一个除以零事件,我会亲自更改零并通知用户我做了。如果这是一个复杂的损坏,那么告诉他们文件是垃圾。
标签: c# debugging exception assert