例外:何时使用,计时,整体使用

时间:2011-05-31 08:09:21

标签: c# .net exception overuse

我会试着问我的问题,所以它不会以一个简单的论证线程结束。

我最近跳进了一个用C#编码的应用程序,我发现了异常机制。我和他们有过一些不好的经历,如下面的

// _sValue is a string
try
{
    return float.Parse(_sValue);
}
catch
{
    return 0;
}

我将其改为:

float l_fParsedValue = 0.0f;
if (float.TryParse(_sValue, out l_fParsedValue))
{
    return l_fParsedValue;
}
else
{
    return 0;
}

结果,我在Visual Studio中的输出不再充斥着像

这样的消息
  

第一次机会System.FormatException blabla

当字符串' - '到达代码段时。我认为使用第二个片段更清晰。

更进一步,我经常看到异常经常使用ilke:“我在这个尝试捕获中做任何我想做的事情,如果出现任何问题,请抓住。”。

现在为了避免陷入错误的误解,我希望你们能帮我清楚地定义如何/何时使用这些例外以及何时坚持使用旧学校“如果......其他”。

提前感谢您的帮助!

6 个答案:

答案 0 :(得分:4)

在特殊情况下你应该抛出异常。即出现意外情况时。如果你希望函数定期抛出一个很可能是错误设计的异常。

在你的例子中,很明显TryParse更好,因为异常似乎经常出现。

但是例如在解析文件时,我希望它几乎总是有效的。所以我通常使用Parse并捕获异常并生成InvalidDataException,并将捕获的异常作为内部异常。通常会简化解析代码,即使它可能是糟糕的样式。

我推荐Eric Lippers的博客文章:Vexing exceptions

答案 1 :(得分:2)

如果是Parse() / TryParse(),最好不要等待异常,请使用TryParse并自行处理不正确的输入。

答案 2 :(得分:2)

异常应该用于异常行为,而不是流量控制。一个基本的指导原则是,如果正常的程序流程经常遇到例外,你就会做错事。

但是,重要的是要注意只有try { } catch { }存在本身不会对性能产生负面影响。只有当实际抛出异常并且需要计算堆栈跟踪时,您才会看到(在某些情况下非常严重)性能下降。

答案 3 :(得分:1)

到目前为止尚未深入研究的另一点是,例外情况需要付出代价。它们颠覆了程序中的正常控制流程,因此有一些资源使用。

一个简单的测试就是编写一个循环遍历原始float.Parse代码的程序,其中包含一些无效数据,并比较运行所需的时间与TryParse版本之间的差异 - 会有一个小但明显的差异。

在做出有关例外的决定时,我想到的一个片段来自this article

  

几乎是规则#1

     

决定是否应该抛出一个   例外,假装扔   声明让电脑发出哔哔声3   时间,并睡2秒。如果   你仍然希望抛弃那些   情况,去吧。

答案 4 :(得分:1)

  

将异常作为一部分的程序   他们的正常处理受到影响   所有的可读性和   经典的可维护性问题   意大利面条代码。

     

- 安迪·亨特和戴夫·托马斯

我认为关于如何/何时使用例外没有简单的正确答案。它取决于您正在处理的应用程序的体系结构和其他因素。

我建议您阅读8.3. Error-Handling Techniques本书的8.4. ExceptionsCode Complete章节。

答案 5 :(得分:0)

啊,如果只是那么简单!但是,唉 - 何时使用例外的决定往往是主观的而不是。不过,您可以使用指南。例如,Microsoft has some

总而言之,抛出异常的经验法则是 - 只有在函数无法完成预期时才会抛出异常。基本上每个函数都有一个契约 - 它具有合法的输入值范围和合法的输出值范围。如果输入值无效,或者无法提供预期的输出值,则应抛出异常。

请注意,这里有一个滑点 - 如果验证(用户输入)错误也会作为异常抛出?一些思想流派说不(包括微软),有些人说是的。你的来电。每种方法都有其优点和缺点,由您决定如何构建代码。

捕获例外的经验法则是 - 您应该只捕获可以处理的异常。现在,这也很滑。是否向用户显示错误消息还“处理”了吗?但如果它是臭名昭着的StackOverflowExceptionOutOfMemoryException怎么办?你很难显示任何东西。那些可能不是唯一可以使整个系统处于不可用状态的例外。再一次 - 你的电话。