对C#来说很新,我想知道如何使用异常?我的意思是,不是一个力学水平,而是一个良好的实践水平。
我将使用例如我的计算器进行标记并转换为RPN并解决RPN中给出的问题。
在标记化步骤中,有各种无效输入,例如“7.7.8”或“^& ##”,我是否应该对未知符号和无效数字有单独的例外?说一个例外,然后一个包含那种错误的方法给予用户是不对的?
我真的无法在这类事情上找到太多材料,所以我想我会问比我更有经验的人。
- - - - 编辑:
感谢大家对你的精彩回应,我今天学到了很多关于我的问题,甚至还有更多的问题。
答案 0 :(得分:15)
从前提条件和后置条件的角度考虑你的词法分析器。以下是设计词法分析器的两种方法:
词法分析器是一种接收格式良好的输入字符串并输出词法分析的设备。输入字符串需要格式良好;如果不是,则词法分析器会因例外而失败。
词法分析器是一种获取输入字符串并进行词法分析的设备。词汇分析包括识别和分析错误条件。
你知道你要传入的字符串是否正确,并且你想要在特殊情况下出现异常错误?或者你不知道字符串是否正确,你希望词法分析者确定吗?
在前一种情况下,抛出异常。在后一种情况下,将错误分析作为词法分析器输出的一部分。
基本上我所说的是do not produce vexing exceptions。令人烦恼的异常非常烦人。如果您的代码的调用者正在调用确定字符串是否正确,那么他们不希望以异常的形式提供该信息,他们希望以表示的数据对象的形式错误分析。如果代码的目的是产生错误分析,则产生如方法的正常操作的分析。不要将分析嵌入到异常中,并让某人捕获异常以获取它。
答案 1 :(得分:3)
根据我的经验,您不应该将异常用作代码的逻辑或控制流的一部分。当存在真正的异常时,您应该使用它。在你的情况下,那就是,例如,当一个非法的角色,首先不应该存在的角色。但是,如果该函数正在验证字符串,则在发现非法字符时不应抛出异常,至少这是我的意见。
当数据库或“应该”存在的文件无法找到时,当缺少密钥/对值时,我会使用异常。
答案 2 :(得分:2)
为程序员而不是用户创建例外。想想对程序员调用方法有用的东西?
如果有专门的错误处理代码,他们应该考虑针对异常的特定原因进行编写,然后提供特定类型的异常,以便它们可以专门为其设置“catch”块。
如果他们应该编写的错误处理代码在各种异常原因中是通用的,那么提供一个更通用的类型异常,这样他们只需针对那个代码进行编码。
答案 3 :(得分:1)
这是关于.Net中异常处理的最佳实践的一个很好的参考。
http://www.codeproject.com/KB/architecture/exceptionbestpractices.aspx
答案 4 :(得分:1)
我喜欢确定异常是否合适的经验法则:如果函数承诺做某事而不做,它应该抛出异常。一个简单的例子是Parse
vs TryParse
。请注意,Parse
函数承诺解析字符串,如果不能解析则抛出异常(例如,因为字符串的格式错误)。 TryParse
承诺尝试进行解析,因此如果无法解析,则不会抛出异常。简而言之,如果你的函数做出了承诺并且未能实现它,你应该抛出异常。
或者:除非您的函数的前提条件不满意,否则不要抛出异常。我将Eric Lippert的Vexing Exceptions解释为讨论哪些类型的前提条件不合适。
答案 5 :(得分:0)
答案 6 :(得分:0)
一般规则是KISS。如果需要,您应该只抛出/创建例外。如果没有人会抓住它,就没有必要创建一整套异常。
在你的情况下,你可以
如果您发现正在捕获异常并解析消息并采取操作,那么应该创建自定义异常/异常。
您可以创建一个具有“类型”字段的自定义异常,但任何依赖异常的设计类型都是错误的。
答案 7 :(得分:0)
所有解析异常应至少共享一个公共基类,以便调用者可以捕获任何解析异常,而不必将它们全部列在catch子句中(并且可能忘记一个)。
你可以沿着制定子类分类的道路前进,但在你需要这样做之前我不打算做出这样明确的区分。如果调用程序对所有解析错误采取相同的操作,那么它们可以都是同一个类,仅通过显示消息变化。如果很明显某些错误需要以不同方式处理,请创建一个子类。围绕用例设计。
作为旁白:我认为如果某个方法无法实现它所承诺的内容,那么它应该抛出异常,从而保护开发人员在失败的情况下不会取得成功。决定做出哪些承诺是一个更大的设计问题,你可以查看现有的解析API以获得灵感。