拥有单一的,可能是常见的通用异常是不好的编程风格?

时间:2010-04-05 00:05:24

标签: c# coding-style

所以在我的程序中我有一些部分,我使用像这样的try catch块

try
{
  DirectoryInfo dirInfo = new DirectoryInfo(someString); 
 //I don't know if that directory exists
 //I don't know if that string is valid path string... it could be anything

 //Some operations here
}
catch(Exception iDontCareWhyItFailed)
{
  //Didn't work? great... we will say: somethings wrong, try again/next one
}

当然我可能会检查字符串是否是有效路径(正则表达式),然后我会检查目录是否存在,然后我可以捕获各种异常,看看为什么我的例程失败并提供更多信息......但是在我的程序中,它并不是必需的。现在我真的需要知道这是否可以接受,以及专业人士对此有何看法/想法。非常感谢您的关注。

8 个答案:

答案 0 :(得分:13)

  • 编写“主线”代码以处理预期的案例。
  • 异常处理代码写入...等待它...... 处理异常情况。这就是为什么它被称为“异常处理代码”。 : - )

如果主线,预期的日常情况是路径不存在,则编写检查路径是否存在的主线代码。如果一个意外的,奇怪的,异常情况是该文件存在但已被另一个用户锁定,请编写一个处理该异常的异常处理程序。

答案 1 :(得分:5)

您不应该对流控制使用异常,因为它会影响性能,异常不是为此目的而设计的。相反,您应该测试Exists属性以检查目录是否存在

答案 2 :(得分:2)

如果你真的不在乎为什么它失败了,而你的程序无法合理地做任何事情来恢复,那么可以做这样的事情;我宁愿维护这样的东西,而不是使用3个try / catch块做同样的事情而不添加任何额外值的代码。我喜欢传达它的异常名称并不重要,这比捕获名为ex的变量更好。

但有些建议:

  1. 如果您要“捕捉并忽略”,请更明确地了解哪些异常类型可以忽略。如果您知道可以忽略FileNotFoundException或任何IOException类,那么就抓住它。

  2. 如果您要捕获通用异常,请考虑在某处记录异常。如果您的try块中存在逻辑缺陷,那么您当前的方法可能是维护噩梦。例如,假设您编写了一个关于数组索引的逐个​​错误...您当前的代码将吞下它并且没有表明发生了比“目录不存在”更重要的事情。

    < / LI>

答案 3 :(得分:1)

这实际上取决于您将如何处理任何这些错误情况。

如果在任何情况下你要退出并只打印Exception,并且你的用户熟悉阅读和理解那种输出,那么它就完全没问题了,你会浪费时间和代码来处理它更具体地说。

另一方面,如果你最终在异常处理代码中有一堆if测试根据发生的异常做了不同的事情,那么很明显的证据表明你应该以不同的方式处理不同的异常。

如果您的用户不是“技术人员”并且想要比异常转储更有用的错误消息,那么您应该自己做更多的自定义错误处理。即使他们是技术人员,他们也可能会欣赏更清晰的错误消息。

没有正确答案。这实际上取决于您的目标用户体验。

答案 4 :(得分:1)

我不建议使用catch-all类型的异常处理程序。相反,您应该查找DirectoryInfo以及它可以抛出的异常类型。然后,您应该在调用构造函数之前尽量避免使用,并且只捕获您预期的异常。所以我的代码看起来像:

try
{
    if ( string.IsNullOrEmpty( someString ) )
        //do something or throw an exception
    if ( someString.Length > 248 )
        //do something or throw an exception

    DirectoryInfo dirInfo = new DirectoryInfo(someString); 

    If ( !dirInfo.Exists )
        //do something or throw an exception

    //path exists and is valid
    //Some operations here
}
catch(SecurityException)
{
  //Didn't work? great... we will say: somethings wrong, try again/next one
}
catch(ArgumentException)
{
  //Didn't work? great... we will say: somethings wrong, try again/next one
}

答案 5 :(得分:0)

您应尽可能进行验证。例外是昂贵的,应尽可能避免。

检查路径和其他验证并不一定能避免异常处理和try块的需要。异常一直发生(目录不存在,网络没有连接)它是意外的,不可预见的异常,try / catch块旨在处理。

答案 6 :(得分:0)

我也对这种懒惰的编码感到内疚,通常在提供“热门”功能的快速周转时。问题是,鉴于新的堆栈不可避免的“热门”功能请求,清理延迟代码成为低优先级,这意味着这种惰性代码会累积。这些懒惰的异常捕获块然后导致吞噬真正意外的问题,突然你的应用程序状态以一种意想不到的方式发生变异。我正在训练自己不要这样做,因为写懒惰的代码就像使用信用卡一样。它可以让你现在提供以后必须交付的东西,但这是在你需要付款的时候让你获得的复合。

答案 7 :(得分:0)

即使你自己检查(它是一个有效的路径,路径存在,你被允许访问它,它没有被锁定等),你仍然需要进行异常处理。虽然看起来不太可能,但没有理由从检查它们到实际访问路径的时间内条件不会发生变化。

只要您首先需要异常处理,为什么要进行冗余检查?无论如何,操作系统必须再次完成它们,而且你可能无论如何都不会让它们正确。

不要担心例外的成本。与执行I / O的成本相比,异常的成本可以忽略不计。

也就是说,没有做任何事情就抓住所有异常并不好。正如Seth所说,要么只捕获IOException,要么记录异常。如果不这样做,那部分代码将很难调试。