【发布时间】:2011-12-31 19:38:33
【问题描述】:
我有问题:
“你更喜欢什么,异常处理还是 if 条件?”
面试。我的回答是异常处理程序仅适用于特殊情况,例如文件写入时的磁盘权限错误。面试官似乎在期待其他答案。正确答案是什么?
编辑:当 if 条件更合适时,通常使用异常处理的任何特定示例?
【问题讨论】:
-
'面试官似乎在期待其他答案'——那你为什么不问他呢?面试时,我对问题的印象总是比对答案的印象更深...
标签: c#
我有问题:
“你更喜欢什么,异常处理还是 if 条件?”
面试。我的回答是异常处理程序仅适用于特殊情况,例如文件写入时的磁盘权限错误。面试官似乎在期待其他答案。正确答案是什么?
编辑:当 if 条件更合适时,通常使用异常处理的任何特定示例?
【问题讨论】:
标签: c#
由于这个问题被标记为“C#”,我们可以参考 .NET Framework 设计指南作为回答这些类型问题的良好起点。这是MSDN上"Exception Throwing"下给出的指导:
如果可能,请勿将异常用于正常的控制流程。除了 对于具有潜在竞争条件的系统故障和操作, 框架设计者应该设计 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 ()检查,后面跟着相应的异常处理逻辑。
【讨论】:
index,或者array[index] 是否包含null 值。所以问题仍然是什么更好。如果使用了无效索引,是否应该抛出异常?或者您是否会只返回一个null 值而没有任何指示发生错误?在数组上使用无效索引也会导致异常,不会返回数组类型的默认值!
array 被声明为int[],因此null 只能表示该值不存在(超出或范围)。是的,调用者不会知道,但是实现者会知道并且不应该使用异常作为控制流,这就是示例的重点。在不引发异常的情况下返回默认值是有效的,尽管此模式通常希望以 TryXxx 方法表示,如下所述:msdn.microsoft.com/en-us/library/ms229009.aspx
就性能而言,异常处理是一项繁重且昂贵的操作。如果您可以通过使用适当的 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 语句”。
【讨论】:
我通常更喜欢使用一些特殊的 undefined 值(例如,对象为 null)来指示某些计算由于输入无效而无法产生有效结果。这意味着我的代码可以成功确定并报告输入数据无效,无法产生有意义的结果。
当我的代码无法完成请求的计算时,我更喜欢使用异常,例如如果包含一些所需数据的文件不存在,如果它无法连接到数据库。
从概念上来说:
【讨论】:
如果您知道程序的确切登录名并知道可能发生的错误,那么您可以编写 if-else 语句,或者在其他情况下您可以尝试捕获异常处理。
【讨论】: