Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/318.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# if条件vs异常处理程序_C# - Fatal编程技术网

C# if条件vs异常处理程序

C# if条件vs异常处理程序,c#,C#,我有个问题: “您喜欢什么,异常处理还是if条件?” 去面试。我的回答是,只有在特殊情况下,如文件写入时出现磁盘权限错误时,才首选异常处理程序。面试官似乎在期待其他答案。正确答案是什么 编辑:当if条件更合适时,通常使用异常处理的任何特定示例?就性能而言,异常处理是一项繁重且昂贵的操作。如果可以通过使用适当的If-else避免捕获异常,则可以提高应用程序的性能 另一方面,if-else块对代码读取器更有意义。与特殊的试接块相比,它们易于理解和维护。它们以更优雅的方式描述程序流程 最后,正如您所说

我有个问题:

“您喜欢什么,异常处理还是if条件?”

去面试。我的回答是,只有在特殊情况下,如文件写入时出现磁盘权限错误时,才首选异常处理程序。面试官似乎在期待其他答案。正确答案是什么


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

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

另一方面,if-else块对代码读取器更有意义。与特殊的试接块相比,它们易于理解和维护。它们以更优雅的方式描述程序流程

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

编辑

我在一些地方看到的一个常见的坏习惯是

 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语句”.

如果您知道程序的确切登录名,并且知道可能发生的错误,那么您可以编写If-else语句,或者在其他情况下,您可以尝试捕获异常处理。

因为这个问题被标记为“C”,我们可以参考.NET Framework设计指南作为回答这些问题的良好起点。这是MSDN上给出的指南,具体如下:

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

下面是一个不良实践的示例,其中处理了异常,但几乎总能避免:

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

    return value;
}
这似乎是人为的,但我经常从较新的程序员那里看到这样的代码。假设对
数组
的读写正确同步,则可以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;
}

即使在上面的例子中,检查您要做的操作是否至少有成功的机会也是很好的。因此,仍然有一个
if()
检查,然后是适当的异常处理逻辑。

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

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

因此,在概念上:

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

“面试官似乎在期待其他答案”——那你为什么不问问他?面试时,我对问题的印象总是比对答案的印象更深刻……在您的“GetItem”示例中,调用方无法确定是否提供了无效的
索引
,或者
数组[index]
是否包含
空值。因此,问题仍然是什么更好。如果使用了无效索引,是否应该引发异常?或者只返回一个
null
值,而不显示发生了错误?对数组使用无效索引也会导致异常,它不会返回数组类型的默认值@comecme:在该示例中,您可以假设
array
被声明为
int[]
,因此
null
只能表示该值不存在(超出范围)。是的,调用者不知道,但是实现者知道并且不应该使用异常作为控制流,这就是示例的要点。在不引发异常的情况下返回默认值是有效的,尽管此模式通常预期用
TryXxx
方法表示,如本文所述:通常转换字符串的类不会是显示错误消息的类。这就是例外存在的原因:它们可以在更高的层次上被捕获。
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();
    }
}