6

因此,我们正在使用Enterprise Library 4.1 异常处理应用程序块来处理记录/处理多项目应用程序中的异常。我们有一些自定义异常并且正在抛出一些异常,其类在 .NET 框架的标准类库中定义(例如 ArgumentException、InvalidOperationException、ArgumentNullException 等)。

今天,我们的团队负责人决定他不希望我们使用后者,因为 .NET 框架会抛出这些类型的异常,并且为了便于使用应用程序块的策略进行过滤,我们应该只使用自定义异常,去就实际使用自定义版本复制 .NET 标准类库异常而言,如Custom ArgumentException、Custom InvalidOperationException 等。

我的问题是,这种方法有什么问题?当时我无法用手指触摸它,但我闻起来不对劲,我无法摆脱对它的不安情绪。我是否担心一些真正无关紧要的事情?我想它只是感觉就像尾巴在这里摇着狗一样......

4

5 回答 5

12

伊克。我不喜欢的是:

  • 它复制了现有类型
  • 它违反了最小惊喜原则
  • 这意味着如果你想在任何地方找到你使用了错误的参数值(比如说),你必须寻找两个异常的类型层次结构,而不是仅仅寻找ArgumentException.

我建议您让您的团队负责人阅读Effective Java 2nd edition的第 60 条。是的,它是关于 Java 而不是 C# - 但原则保持不变。

于 2009-03-12T22:06:25.633 回答
4

Krzysztof Cwalina 和 Brad Abrams的框架设计指南书(第一版)建议尽可能抛出System命名空间中定义的现有异常,并且越具体越好。如果不合适,则抛出自定义异常。

创建一个自定义ArgumentNullException的平行宇宙来匹配System.ArgumentNullException是重复的工作,我看不到任何价值。归根结底,如果你的代码抛出一个System.ArgumentNullException而不是框架类,你可以从堆栈跟踪中确定谁最终负责.

当涉及到代码维护时间时,这对于现在和将来来说是不必要的额外工作。

于 2009-03-12T22:14:13.617 回答
4

我回应 Jon Skeet 和 Kev 的回答。我只想补充一点,如果您的异常策略想要处理与您自己的异常不同的框架级异常,请考虑使用异常的堆栈跟踪。

// Somewhere within a custom exception handler policy
var frame = new StackTrace(exception).GetFrame(0);
if (frame.GetMethod().DeclaringType.Namespace.StartsWith("MyNamespace.")) 
{
    // Handle exceptions from our code
}
else 
{
    // Handle framework-level exceptions
}
于 2009-03-12T22:21:11.900 回答
1

好吧,您的代码抛出的异常和 .net 基类抛出的异常都应该以相同的方式处理。

两者都可能是您的代码中出现问题的症状,因此两者都不应该被忽略或过滤!

于 2009-03-12T22:01:16.393 回答
0

当异常正确地描述了您试图暴露的问题类型时(例如,当参数为空时,您应该抛出 ArgumentNullException),抛出 .Net 异常很好。如果您发现 .Net 框架无法处理的情况(例如,您想将 6 除以 3,但您的应用程序不允许这样做),您应该创建一个自定义异常。

于 2009-03-12T22:16:43.957 回答