if-condition与异常处理程序

Nem*_*emo 19 c#

我有一个问题:

"你更喜欢什么,例外处理或条件?"

面试.我的回答是异常处理程序仅在特殊情况下(例如文件写入时的磁盘权限错误)首选.面试官似乎期待着其他一些答案.什么是正确的答案?

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

bob*_*mcr 23

由于此问题标记为"C#",因此我们可以将.NET Framework设计指南称为回答这些类型问题的良好起点.这是MSDN在"Exception Throwing"下给出的指导:

如果可能,不要将异常用于正常的控制流程.除了系统故障和具有潜在竞争条件的操作之外,框架设计者应该设计API,以便用户可以编写不会抛出异常的代码.例如,您可以在调用成员之前提供检查前提条件的方法,以便用户可以编写不会引发异常的代码.

以下是一个不良做法的示例,其中处理异常但几乎总是可以避免:

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

    return value;
}
Run Code Online (Sandbox Code Playgroud)

这似乎是人为的,但我经常从新的程序员那里看到这样的代码.假设读取和写入之间的正确同步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;
}
Run Code Online (Sandbox Code Playgroud)

在其他情况下,您无法合理地避免异常,只需要处理它们.当您必须处理外部资源(例如文件或网络连接)时,最常遇到这种情况,您可能会随时失去对其的访问权限或与之联系.来自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();
    }
}
Run Code Online (Sandbox Code Playgroud)

即使在上面的示例中,最好检查您要执行的操作是否至少有成功的机会.所以仍然有一个if ()检查,然后是相应的异常处理逻辑.

  • @comecme:在那个例子中,你可以假设`array`被声明为`int []`,所以`null`只能表示该值不存在(out或range).是的,调用者不会知道,但是实现者*将*知道并且不应该使用异常作为控制流,这是示例的要点.在不抛出异常的情况下返回默认值是有效的,尽管通常期望这种模式用`TryXxx`方法表示,如下所述:http://msdn.microsoft.com/en-us/library/ms229009的.aspx (2认同)

Har*_*san 10

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

另一方面,如果else块对代码阅读器更有意义.与特殊的try catch块相比,它们易于理解和维护.他们以更优雅的方式描述程序流程

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

编辑

我在某些地方看到的常见坏习惯就是这样

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

现在尝试使用if else可以很容易地避免使用if

  string str = "Some String"
  int i;
    if(!int.TryParse(str, out i))
    {
       MessageBox.Show("Invalid input");          
    }
Run Code Online (Sandbox Code Playgroud)