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