在下面的代码中,NDepend报告违规,因为嵌套深度为6(每个catch为1),限制为5.因此它会在this rule中标记:
重构方法的快速摘要
对于更一般的IOException只有一个catch,并且在该catch中有代码区分DirectoryNotFound,PathTooLong和其他IOException是最好的方法吗?我不想增加嵌套深度限制,因为它是大多数情况下的有效限制。那么没有例外是在同一层次结构中并且组合不是一种选择的情况呢?是创建一个属性并改变规则来禁用违反此方法的唯一方法吗?
private static void _TryDeleteFile(string filename)
{
try
{
File.Delete(filename);
}
catch (ArgumentException innerEx)
{
// do something
}
catch (DirectoryNotFoundException innerEx)
{
// do something
}
catch (PathTooLongException innerEx)
{
// do something
}
catch (IOException innerEx)
{
// do something
}
catch (NotSupportedException innerEx)
{
// do something
}
catch (UnauthorizedAccessException innerEx)
{
// do something
}
}
答案 0 :(得分:2)
首先,try / catch块在c#中并不像它们那样优雅,而这正是我们现在必须要考虑的事情。
其次,有许多方法可以减少嵌套,但它们总是以牺牲其他形式的复杂性为代价,所以你需要小心。请记住,NDepend建议您减少嵌套,因为它猜测您的代码可能难以阅读或维护。这可能是错的,或者可能是因为你有可用的工具没有更好的选择。
在我看来,前进的方向实际上取决于你在每个捕获区内所做的工作。如果非常简单,例如只返回字符串错误消息而没有别的,那么我认为你的代码会很好。但是,如果您在每个块中执行不同类型的逻辑,特别是如果您对不同的异常类型重复使用逻辑,那么您的代码可能会变得混乱。
重构可能是在字典,工厂类或IOC内核中保留“异常处理程序”(类或操作)的集合。然后,您可以在一行代码中获取异常处理程序。这将减少嵌套,但会引入其自身的复杂性。像这样:
try
{
/* Your code */
}
catch(Exception ex)
{
var exceptionHandler = _exceptionHandlers[ex.GetType()];
exceptionHandler.Execute(ex);
}
有许多不同的方法可以实现基本相同的东西:你将每个逻辑块推入它自己的类/方法/ lambda然后你有一个中间类/方法/字典,用于获取正确的逻辑。