如何在使用if / else与try / catch之间做出选择?

问题描述

| 在编写代码时,如何决定是否使用if / else或try / catch?例如,在检查文件时,这应该基于if / else(if(File.Exists))还是try / catch块? 例如,可以通过if / else块来处理写入文件的操作,以创建文件然后写入文件,或者通过假定文件存在的尝试/捕获操作。选择时有哪些注意事项? 谢谢     

解决方法

        绝对不要将try / catch用于流量控制。 产生异常是非常昂贵的动作。如果/其他更快,更干净。     ,        处理文件时,应始终使用try / catch,因为文件的状态可以在程序外部更改。 考虑以下代码位:
if(File.Exists(\"file.txt\"))
    File.Delete(\"file.txt\")
在if语句之后,ѭ1调用之前,该文件可能已被另一个进程删除。当您尝试将其删除时,会引发异常。 在处理文件时,还有很多事情要考虑,您可能无法使用ifs,例如,文件位于网络连接上不可用,访问权限更改,硬盘故障等。 这些事情不在程序的控制范围之内,因此您应该具有异常处理程序。     ,        如果您认为该操作通常会成功,那么
try/catch
会更容易阅读。特别是如果有很多原因导致故障(多个“ 3”个块)。 否则,如果它有时成功但有时失败-并且由于特定原因而这样做,则使用
if/else
(这被称为结构化异常处理)。 有人指出使用
try/catch
进行异常处理会很费时。我倾向于按以下方式阅读这样的建议:如果您的性能分析表明性能问题,请不要在紧缩的内部循环中这样做。在编写初稿时,根本不必考虑在此级别进行优化!     ,        只是为了平息这个话题(是的,这个问题是在8个月前提出的,但是互联网一直都知道!),我决定进行一点测试,如果您确定不会,那将更有效有一个例外-例如,“其他”部分只会发生0.001%的时间。事实证明,如果您不必捕获/删除其他任何内容,那么try-catch大约快4%(无论如何在我的机器上)。这是代码和附带的结果: 案例1:if-else:
var startTime = DateTime.Now;
int bazillion = 100000000;
int[] list = {1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20};
for (int i = 0; i < bazillion; i++)
{
    for (int k = 0; k < list.Length; k++)
    {
        if (k >= 0)
        {
            list[k] = i;
        }
        else
        {
            // do nothing.
        }
    }
}
var executionTime = DateTime.Now - startTime;
Debug.WriteLine (executionTime.TotalMilliseconds);
5次运行的执行时间(毫秒):7441.4256、7392.4228、7545.4316、7531.4308、7323.4188。 平均值= 7446.82592毫秒 案例2:尝试捕获:
var startTime = DateTime.Now;
int bazillion = 100000000;
int[] list = { 1,20 };
for (int i = 0; i < bazillion; i++)
{
    for (int k = 0; k < list.Length; k++)
    {
        try
        {
            list[k] = i;
        }
        catch (Exception e)
        {
            // do nothing
        }
    }
}
var executionTime = DateTime.Now - startTime;
Debug.WriteLine(executionTime.TotalMilliseconds);
5次运行的执行时间(毫秒):7258.4152、7137.4083、7070.4044、7052.4033、7120.4073 平均值= 7127.8077毫秒 结论(基于这个相当简单的示例;实际里程可能会有所不同,等等): 就绝对数字而言,如果您十分确定不会发生例外/其他情况,则try-catch大约比每次必须执行\“ if \”子句快4%。     ,        当可能发生意外(异常)并且您想对此做一些特殊的事情时,可以使用try / catch:
try
{
   //Do something that might rise an exception,say a division by 0
   //this is just an easy example as you might want to check if said value is not 0
   //before dividing
   int result = someNumberOfMine / anUnsafeNumber;
}
catch
{
   //if something unexpected happened,do a special treament
}
在您的特定情况下,我将建议使用File.Exists来验证文件的存在,而不是使用try / catch块,因为可以在执行任何操作之前检查文件的存在与否。     ,        仅在特殊情况下才应使用例外处理。 在取决于文件是否存在的情况下,仅在您可以做到的情况下使用try catch块就没有意义
if(File.Exists(path))
{
}
else
{

}
异常处理会严重影响性能,因此请尝试在代码中应用更多检查,例如if10ѭ,以尽量减少异常情况     ,        一般来说,这取决于 对于基于文件的内容,您几乎总是想尝试操作并处理失败,而不是先检查。原因是文件系统是共享资源,您不能保证在file.exists返回true之后,该文件确实存在,因为某些其他进程可能已将其删除。     ,正如一些答案已经指出的那样,这取决于。 If / else用于流控制,但Exception也可以用于捕获发生的错误。但是正如Turowicz指出的那样,对很多人来说,使用try / catch而不是您必须达到的最低限度是一种不好的做法。 您总是可以阅读Ned Batchelder(关于返回码,作为使用异常的替代方法)和Joel Spolsky(为什么他不喜欢使用异常编程)的这些文章,以了解其他人对异常的看法,然后做出你自己的想法。     ,        只是一个想法……答案之一是,例如,如果您被零可能性除法,则应进行尝试。我想知道为什么?您在这里处于控制之中,可以在划分之前进行检查并采取行动。如果它为零,则只需要进行除法,而只需执行另一个逻辑即可。 我只会在您无法控制或无法(或没有任何意义)事先检查(打开文件等)的情况下使用try catch。 在您的情况下,我将使用File.Exists并尝试/捕获。 File.Exist作为业务检查存在(当它不存在时无需打开它),尝试/捕获以捕获打开文件时可能发生的任何异常。     ,        如果预计该文件不存在,请首先检查是否存在。但是,当丢失的文件为异常状态时,您应该指示此异常状态,并带有例外。 因此,基本思想是: 尽量避免在预期情况下出现异常情况。     ,        通常,您应该同时执行这两项操作。 尝试/捕获以避免异常情况(文件突然从另一个线程中删除)。并且如果/其他处理非异常(检查文件是否存在)。尝试/捕获比通常的if / else相对要慢,因此不值得将其用于所有功能。     ,        在做出此类决定时,格言“例外应为例外”很有用。原则是您应使用标准程序流(例如if语句)处理已知情况,以便异常代表意外情况(例如bug)。 当然,像任何规则一样,它也有可能被打破。 另外,我也不会太担心异常处理对性能的影响。除了极端情况外,开销几乎可以忽略不计。     ,        为此,您知道文件退出问题。因此,您更愿意选择其他方式。 如果您不知道问题所在,最好使用try catch。 我建议两者,如下所示
try 
{
  if(File.Exists(path)) 
  { 
     do work
  } 
  else 
  {
     messagebox.show(\"File Path Not Exit\");
  } 
}
catch(Exception e) 
{
 messagebox.show(e); 
}
它捕获了所有我们没有想到的错误。     ,        从所有答案中都可以明显看出,没有标准/批准的方式来决定您应该使用一种还是另一种。如果正确完成,这两种方法都将有效。如果做错了,两种方法都将是无效的。 当有意义时(即在我自己的函数内部),我更喜欢if / else语句;当我调用无法控制的函数时,我更喜欢使用try块。 在上面的示例中,如果您控制文件,则File.Exists()就足够了(意味着没有其他程序可以操纵它),但是如果文件在检查和使用之间可能消失了,则还不够。 根据我的经验,一般而言,在大多数情况下,文件操作都可以更好地处理异常,因为在c#中,这些非常文件操作会引发异常。它们不返回可以使用if语句检查的错误代码。     

相关问答

Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其...
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。...
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbc...