我在我们的项目中继承了代码,看起来像这样。这是班上的一种方法。
protected override bool Load()
{
DataAccess.SomeEntity record;
try
{
record = _repository.Get(t => t.ID.Equals(ID));
if (record == null)
{
throw new InvalidOperationException("failed to initialize the object.");
}
else
{
this.ID = record.ID;
// this.OtherProperty = record.SomeProperty;
// etc
}
}
catch (Exception)
{
throw;
}
return true;
}
如果我从我的UI层调用此Load方法,我可能想要一个try catch块来捕获由于加载实例失败而导致的任何异常,例如: InvalidOperationException,但上面的代码对我来说不对。
catch语句不会吞下InvalidOperationException吗?该catch语句还将捕获_repository.Get的潜在问题,以及在记录有效时设置属性的潜在问题。
我认为我应该通过添加更多try catch语句来重组它来分别处理Get操作和属性设置操作,或者添加更多catch块来处理不同的异常,但我问了一位同事,他建议try catch是在这种情况下无关紧要,应该完全删除,如下所示:
protected override bool Load()
{
DataAccess.SomeEntity record;
record = _repository.Get(t => t.ID.Equals(ID));
if (record == null)
{
throw new InvalidOperationException("failed to initialize the object.");
}
else
{
this.ID = record.ID;
// this.OtherProperty = record.SomeProperty;
// etc
}
return true;
}
我想要一些第二意见,我刚开始对异常处理感兴趣,所以我想确保按照最佳实践以正确的方式进行。
答案 0 :(得分:6)
执行此操作时:
catch (Exception)
{
throw;
}
您基本上没有处理异常。然而,这并不意味着你无视它。 throw
语句会将异常传播到堆栈中。为了清晰可读的代码,你的最后一个例子要好得多。
答案 1 :(得分:0)
如果你在调用方法(Ithink)中捕获异常,你应该只捕获你期望的异常。如果异常是Load()的问题,则向调用方法抛出一个新的异常,并提供有关该异常的更好信息。
答案 2 :(得分:0)
出色!你肯定是在正确的轨道上。之前的实现除了重新抛出不必要的异常之外什么都不做。您应该只处理业务层中预期的特定异常,否则让它们自然地将调用堆栈上升到UI层。
作为最佳实践,只有在想要添加一些额外的调试信息时才重新抛出异常,在这种情况下,您需要定义自定义异常
答案 3 :(得分:0)
异常将被catch
语句捕获,但由于它有一个throw
语句,它会抛出异常。这与你根本没有try / catch有同样的效果,所以你的同事建议把它留下来是正确的。
如果您没有以任何方式实际处理异常,那么添加异常处理代码没有太大意义。
答案 4 :(得分:0)
我同意你的同事,你应该只捕捉你知道需要被抓住的例外情况。我通常会忽略任何尝试捕获块,除非我确切知道为什么在特定情况下我需要它。这是因为如果只是将try catch块放在所有内容中,你倾向于隐藏代码中的真正错误。关闭错误处理,直到你绝对需要它为止 - 在应用程序的最高点启动一个全局错误处理程序 - 如果这是asp.net你可以挂钩应用程序错误事件并在那里记录错误,但我的观点是除非你知道为什么要添加它们并编写处理错误情况的代码而不是捕获它们,否则不要添加try catch块。
享受!