如果我有这样的事情怎么办?
try
{
//work
}
catch (ArgumentNullException e)
{
HandleNullException();
Logger.log("ArgumentNullException " + e);
DoSomething();
}
catch (SomeOtherException e)
{
HandleSomeOtherException();
Logger.log("SomeOtherException " + e);
DoSomething();
}
catch (Exception e)
{
HandleException();
Logger.log("Exception " + e);
DoSomething();
}
现在我们可以看到,我正在尝试处理一些不同情况的异常。但是每当引发异常时,我总是在最后调用方法DoSomething()
。如果有异常,是否有更智能的方法来调用DoSomething()
?如果我添加了一个finally
块并在那里调用了DoSomething()
,那么即使没有异常,也会一直调用它。有什么建议吗?
答案 0 :(得分:9)
如果我添加了
finally
块并在那里调用了DoSomething()
,那么即使没有例外,也会一直调用它。
您所寻找的内容在CLI standard(分区IIA,第18章)中称为fault handler。尽管.NET实现了它们,但C#语言并不直接支持它们。但是,他们可以被模仿:
bool success = false;
try
{
…
success = true;
}
catch (…)
{
…
}
…
finally
{
if (!success)
{
DoSomething();
}
}
请注意,不需要在每个catch
处理程序中设置标志,因为这里的一些答案建议。简单地否定测试,您只需要在try
块的末尾设置一次标志。
答案 1 :(得分:5)
您可以使用以下代码实际上 删除冗余。
try
{
//work
}
catch (Exception e)
{
Handle(e);
}
Handle
方法的位置:
static void Handle(Exception e)
{
var exceptionType = e.GetType();
//Use an if/else block, or use a Dictionary<Type, Action>
//to operate on your exception
Logger.log(exceptionType + " " + e);
DoSomething();
}
答案 2 :(得分:2)
你现在正在做的事情和它一样好。
如果你需要在发生异常时调用此函数,而不是其他情况,并且你必须有不同的代码来处理不同的异常,这是最好的。
答案 3 :(得分:2)
每当抛出异常时,您都可以设置一个布尔值,使用finally
并检查布尔值。 (或者反过来,只有在没有抛出异常时才设置布尔值,如下所示:)
bool noException = false;
try
{
//work
noException = true;
}
catch (ArgumentNullException e)
{
HandleNullException();
Logger.log("ArgumentNullException " + e);
}
catch (SomeOtherException e)
{
HandleSomeOtherException();
Logger.log("SomeOtherException " + e);
}
catch (Exception e)
{
HandleException();
Logger.log("Exception " + e);
}
finally
{
if (!noException)
DoSomething();
}
答案 4 :(得分:2)
为什么不呢:
try
{
//work
}
catch (Exception e)
{
if (e is ArgumentNullException)
HandleNullException();
else if (e is SomeOtherException)
HandleSomeOtherException();
else
HandleException();
Logger.log(e.GetType().Name + " " + e);
DoSomething();
}
记录的类型名称将是实际的运行时类型,因此,例如"IndexOutOfRangeException"
可能会被记录而不仅仅是"Exception"
如果你是第三种情况,但我认为这是一个改进你现在有。
编辑:上面的代码看起来非常糟糕,if
- else if
逻辑检查类型。如果我们引入了多态性,它可能会更漂亮:
try
{
//work
}
catch (HandleableException e)
{
e.Handle(); // this calls a **virtual** method, each override does what's relevant
Logger.log(e.GetType().Name + " " + e);
DoSomething();
}
当然,如果我们无法修改某些Exception
类,则无法为其提供Handle()
方法。 .Handle()
也可以是扩展方法(而不是virtual
实例方法),但是必须在该方法内完成类型检查(丑陋代码)。然后这与Eve的回答非常相似。
答案 5 :(得分:1)
你可以这样做:
Exception caughtException = null;
try {
...
} catch(ExceptionType1 e1) {
...
caughtException = e1;
} catch(ExceptionType2 e2) {
...
caughtException = e2;
} catch(ExceptionType3 e3) {
...
caughtException = e3;
}
if (caughtException != null) {
// Put your common exception code here
DoSomenthing();
// You can pass caughtException to functions, too
LogException(caughtException);
}
除非发现异常,否则 caughtException
将为null
。您可以使用它来决定是否致电DoSomenthing
。