【发布时间】:2011-11-17 20:18:15
【问题描述】:
.Net 框架的 try-catch 实现只允许您捕获继承自基类“System.Exception”的类型。为什么这不是“System.IException”之类的接口?
用例
我们在每个继承 System.Exception 的 API 中使用自定义基类。这仅在记录异常后才抛出,因此我们可以通过以下方式轻松避免重新记录:
try
{
// Do something.
}
catch (LoggedException)
{
// Already logged so just rethrow.
throw;
}
catch (Exception ex)
{
// TODO: Log exception.
throw new LoggedException("Failed doing something.", ex);
}
这很好,直到您想要一个继承另一个系统异常类型(例如 System.FormatException)的自定义异常
现在处理这两种情况的唯一方法是拥有两个自定义基类型并复制每个 catch 语句。
重构
如果 .net 框架只是简单地查找诸如 System.IException 之类的东西,那么您可以简单地拥有一个自定义异常接口,例如 CompanyName.ILoggedException,继承您所有自定义异常类型实现的 System.IException。因此,您的新 catch 代码将类似于:
try
{
// Do something.
}
catch (ILoggedException)
{
// Already logged so just rethrow.
throw;
}
catch (IException ex)
{
// TODO: Log exception.
throw new CustomException("Failed doing something.", ex);
}
这样实现框架是否有实际原因?或者这会是 .Net 框架的未来版本中需要的东西吗?
【问题讨论】:
-
您知道您可以简单地在
catch (Exception ex)中使用is运算符,对吧?if (ex is ILoggedException) -
@xanatos : 但这是一个 hack/workaround,而不是内置功能
-
@xanatos 是的,在发布后也想到了这一点,但我个人非常希望在未来的版本中看到类似的东西......也许我们可以实现它!
-
我能想到相当多的案例,人们不禁想知道为什么会做出这样那样的设计决定,有些甚至设计师/MS 开发人员也可能想重新审视 (@987654321 @),但是像异常处理这样的东西需要一个比你提供的更强大的案例。
-
@sll 这不是 hack,还有另一个 C# keyword:as, ILoggerException l = ex as ILoggerException; if (l != null) { l.WriteLog();扔前; }
标签: c# .net exception interface exception-handling