我会试着问我的问题,所以它不会以一个简单的论证线程结束。
我最近跳进了一个用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:“我在这个尝试捕获中做任何我想做的事情,如果出现任何问题,请抓住。”。
现在为了避免陷入错误的误解,我希望你们能帮我清楚地定义如何/何时使用这些例外以及何时坚持使用旧学校“如果......其他”。
提前感谢您的帮助!
答案 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. Exceptions和Code Complete章节。
答案 5 :(得分:0)
啊,如果只是那么简单!但是,唉 - 何时使用例外的决定往往是主观的而不是。不过,您可以使用指南。例如,Microsoft has some。
总而言之,抛出异常的经验法则是 - 只有在函数无法完成预期时才会抛出异常。基本上每个函数都有一个契约 - 它具有合法的输入值范围和合法的输出值范围。如果输入值无效,或者无法提供预期的输出值,则应抛出异常。
请注意,这里有一个滑点 - 如果验证(用户输入)错误也会作为异常抛出?一些思想流派说不(包括微软),有些人说是的。你的来电。每种方法都有其优点和缺点,由您决定如何构建代码。
捕获例外的经验法则是 - 您应该只捕获可以处理的异常。现在,这也很滑。是否向用户显示错误消息还“处理”了吗?但如果它是臭名昭着的StackOverflowException
或OutOfMemoryException
怎么办?你很难显示任何东西。那些可能不是唯一可以使整个系统处于不可用状态的例外。再一次 - 你的电话。