if条件vs异常处理程序

本文关键字:异常处理程序 vs 条件 if | 更新日期: 2023-09-27 18:19:12

我明白你的问题了:

"你更喜欢什么,异常处理还是if-condition?"

面试。我的回答是,异常处理程序只适用于特殊情况,比如文件写入时出现磁盘权限错误。面试官似乎在期待别的答案。正确答案是什么?

编辑:当if条件更合适时,异常处理通常使用的任何特定示例?

if条件vs异常处理程序

由于这个问题被标记为"c#",我们可以参考。net框架设计指南作为回答这类问题的一个很好的起点。这是MSDN在"Exception throws "下给出的指导:

如果可能,不要对正常的控制流使用异常。除了对于系统故障和具有潜在竞争条件的操作,框架设计者应该设计api以便用户可以编写代码这不会抛出异常。例如,您可以提供一种方法来在调用成员之前检查先决条件,以便用户可以写入不抛出异常的代码。

下面是一个实践的例子,异常被处理,但几乎总是可以避免的:

public int? GetItem(int index)
{
    int? value = null;
    try
    {
        value = this.array[index];
    }
    catch (IndexOutOfRangeException)
    {
    }
    return value;
}

这似乎是人为的,但我经常从新程序员那里看到这样的代码。假设对array的读写有适当的同步,则可以100%确定地避免此异常。鉴于此,编写该代码的更好方法如下:

public int? GetItem(int index)
{
    int? value = null;
    // Ensure the index is within range in the first place!
    if (index >= 0 && index < this.array.Length)
    {
        value = this.array[index];
    }
    return value;
}

在其他情况下,您无法合理地避免异常,只需要处理它们。这是最常见的情况,当你必须处理外部资源,如文件或网络连接,你可能会失去访问或联系在任何时候。来自WCF的例子:

public void Close()
{
    // Attempt to avoid exception by doing initial state check
    if (this.channel.State == CommunicationState.Opened)
    {
        try
        {
            // Now we must do a (potentially) remote call;
            // this could always throw.
            this.channel.Close();
        }
        catch (CommunicationException)
        {
        }
        catch (TimeoutException)
        {
        }
    }
    // If Close failed, we might need to do final cleanup here.
    if (this.channel.State == CommunicationState.Faulted)
    {
        // local cleanup -- never throws (aside from catastrophic situations)
        this.channel.Abort();
    }
}

即使在上面的例子中,最好检查一下您将要执行的操作至少有成功的机会。所以仍然有一个if ()检查,后面跟着适当的异常处理逻辑。

就性能而言,异常处理是一项繁重而昂贵的操作。如果您可以通过使用适当的If else来避免捕获异常,则可以提高应用程序的性能

另一方面,if else块对代码读者来说更有意义。与异常的try catch块相比,它们易于理解和维护。它们以更优雅的方式描述程序流程

最后,正如你所说,异常处理应该用于不确定的情况或特殊情况它不应该是默认选择

编辑

我在一些地方看到的一种常见的不良做法是:

 try
 {
     string str = "Some String"
     int i = Convert.ToInt32(str);
 }
 catch (Exception ex)
 {
      MessageBox.Show("Invalid input");          
 }

现在可以通过使用if else

很容易地避免在这种情况下使用try catch
  string str = "Some String"
  int i;
    if(!int.TryParse(str, out i))
    {
       MessageBox.Show("Invalid input");          
    }

正确答案就是你给出的那个。

为了更具体,你应该这样说:"由于捕获和抛出异常的开销,我尽可能使用if语句"。

我通常更喜欢使用一些特殊的未定义的值(例如对象为null)来表示由于无效输入而导致某些计算无法产生有效结果。这意味着我的代码可以成功地确定并报告输入数据无效,并且不能产生有意义的结果。

我更喜欢在我的代码不能完成请求的计算时使用异常,例如,如果包含某些所需数据的文件不存在,如果它不能连接到数据库。

所以概念上:

  • 未定义的结果(加上if-condition):程序成功确定给定输入没有有效输出。
  • 异常(加上try-catch):由于应用程序中与输入无关的错误,程序无法完成计算。

如果你知道程序的确切登录,并且知道可能发生的错误,那么你可以写If -else语句,或者在其他情况下,你可以把事情留给catch异常处理。