【问题标题】:What are industry standard best practices for implementing custom exceptions in C#?在 C# 中实现自定义异常的行业标准最佳实践是什么?
【发布时间】:2011-06-15 01:51:45
【问题描述】:

在 C# 中实现自定义异常的行业标准最佳实践是什么?

我查了谷歌,有很多推荐,但我不知道哪些更可信。

如果有人有权威文章的链接,那也很有帮助。

【问题讨论】:

  • 类似于bit.ly/hVTSgp 我建议您通过进一步解释您要查找的内容来缩小您的主题范围。
  • 我的老板希望我为我编写的程序创建一个自定义异常类,以便我们可以轻松识别特定错误。这将是:特定 Excel 单元格中没有数据、超出范围的异常(可以使用此标准)、未按特定顺序上传的数据等。
  • 听起来您正在使用异常来处理业务逻辑流程 - 应尽可能不使用异常来处理预期问题。
  • @ck - 老实说,我认为您可能是对的。我现在要回顾我的代码并尝试将它们更改为以不同的方式处理。谢谢。

标签: c# custom-exceptions


【解决方案1】:

我假设您正在寻找异常处理实践。所以看看下面的文章,

http://msdn.microsoft.com/en-us/library/ms229014.aspx //给出关于异常的总体思路,包括自定义异常

http://blogs.msdn.com/b/jaredpar/archive/2008/10/20/custom-exceptions-when-should-you-create-them.aspx //

【讨论】:

    【解决方案2】:

    创建自定义异常的标准是派生自Exception。然后,您可以引入自己的属性/方法和重载的构造函数(如果适用)。

    这是一个自定义ConnectionFailedException 的基本示例,它接受一个特定于异常类型的额外参数。

    [Serializable]
    public class ConnectionFailedException : Exception
    {
        public ConnectionFailedException(string message, string connectionString)
            : base(message)
        {
            ConnectionString = connectionString;
        }
    
        public string ConnectionString { get; private set; }
    }
    

    在应用程序中,这可以用于应用程序尝试连接到数据库的场景,例如

    try
    {
        ConnectToDb(AConnString);
    }
    catch (Exception ex)
    {
        throw new ConnectionFailedException(ex.Message, AConnString);
    }
    

    然后由您来处理更高级别的ConnectionFailedException(如果适用)

    也可以看看Designing Custom ExceptionsCustom Exceptions

    【讨论】:

    • 为什么不只捕获 ConnectionFailedException 类型的异常更有目的性?
    • @Anar 该示例显示了如何您提高ConnectionFailedException 的期望是您会在调用堆栈的更高位置捕获它。您可以捕获从ConnectToDb 引发的更有意义的异常,而不是一般的Exception,但是,它只是用于演示目的。
    • 你的意思是它可能是ConnectionFailedException 这不是重点,对吧?
    • @Anar 抱歉,我不确定我是否理解您要问的是什么?
    • @SalmanAbbas "这是一个基本示例..." - 关键字是 "basic" 和 "example "。
    【解决方案3】:

    这是创建自定义异常的代码:

    using System;
    using System.Runtime.Serialization;
    
    namespace YourNamespaceHere
    {
        [Serializable()]
        public class YourCustomException : Exception, ISerializable
        {
            public YourCustomException() : base() { }
            public YourCustomException(string message) : base(message) { }
            public YourCustomException(string message, System.Exception inner) : base(message, inner) { }
            public YourCustomException(SerializationInfo info, StreamingContext context) : base(info, context) { }
        }
    }
    

    另请参阅:http://www.capprime.com/software_development_weblog/2005/06/16/CreatingACustomExceptionClassInC.aspx

    【讨论】:

    • FWIW - 这几乎正是使用 Visual Studio 中包含的 Exception sn-p 所产生的结果。
    • 优秀。我在 2005 年写了这篇博文,但我认为有一些来自 Microsoft 的指导,我以此为基础,看起来该指导通过 sn-p 编入了 VS。
    • 你不需要你的类上的 impelments ISerializableException 已经实现了它并且你正在从它继承)并且你的最后一个(第四个)构造函数可以被保护(它在Exception).
    【解决方案4】:

    我使用自定义异常来传达错误的性质。

    例如,我喜欢使用框架提供的“ArgumentNullException”来检查参数。然后,当我在调试器或错误日志中看到此错误时,我立即知道错误的性质,而无需进一步阅读。

    光谱的另一端是 InvalidOperationException,它可能意味着几乎任何事情。

    自定义异常的替代方法是详细的错误消息。没关系,但是通过自定义异常(例如 ConnectionFailed)更有意义。然后消息本身可以提供更详细的信息。

    创建此类自定义异常时,我不添加任何新属性。这样做的原因是,如果您有一个错误记录器,您希望它能够处理所有异常。如果您添加一个特殊属性,那么错误记录器将忽略它。例如,如果您使用 MSTest,当您运行测试但测试失败时,不会显示自定义属性。但是如果你坚持使用基类的 Message 属性,它会显示得很好。

    所以子类化很简单:

    public class NavigationException : Exception{
        public NavigationException() {}
        public NavigationException(string msg) : base(msg) {}
        public NavigationException(string msg, Exception inner) : base(msg, inner) {}
    }
    

    这非常简单,适用于任何错误记录器,当我看到它时,我知道这是一个导航问题,如果需要我可以查看详细信息。

    格雷格

    【讨论】:

      猜你喜欢
      • 2011-06-13
      • 1970-01-01
      • 2010-10-12
      • 2014-07-08
      • 1970-01-01
      • 2010-10-15
      • 2013-01-13
      • 2018-08-08
      • 1970-01-01
      相关资源
      最近更新 更多