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


72

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

我已经检查过Google,并且有很多建议,但是我不知道哪个建议更可信。

如果有人与权威文章有任何链接,那也将有所帮助。


1
bit.ly/hVTSgp相似,我建议您通过进一步解释所要查找的内容来缩小主题范围。
Uwe Keim

我的老板希望我为我编写的程序创建一个自定义异常类,以便我们可以轻松识别特定错误。这将是喜欢的东西:在一个特定的Excel单元格中没有任何数据,outofrange异常(可以使用此标准),按特定顺序等没有上传数据
达伦·杨

7
听起来您正在使用异常来处理业务逻辑流-预期的问题应在不使用异常的情况下进行处理。
cjk 2011年

@ck-我认为您可能是诚实的。现在,我将回顾我的代码,并尝试更改它们以不同的方式进行处理。谢谢。
达伦·杨

Answers:


68

创建自定义异常的标准是从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在更高级别上进行处理(如果适用)

也可以看一下设计自定义异常自定义异常


为什么不更有目的地仅捕获ConnectionFailedException类型的异常?
anar khalilov

@Anar示例显示了如何提高ConnectionFailedException期望值,因为您将在调用堆栈中获得更高的期望。您可能会发现一个更有意义的例外,ConnectToDb而不是一般问题Exception,但这只是出于演示目的。
詹姆斯,

您的意思是本来可以ConnectionFailedException,但这不是重点,对吗?
anar khalilov

@Anar对不起,我不确定我是否理解您要问的是什么?
詹姆斯,

1
@SalmanAbbas “这是一个基本示例...” -关键字为“基本”和“示例”。
詹姆斯(James)

11

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

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


1
FWIW-这几乎就是使用ExceptionVisual Studio中包含的代码片段所产生的结果。
乔恩·彼得森

优秀的。我在2005年撰写了博客文章,但我认为我有一些基于Microsoft的指南,并且该指南似乎是通过代码片段编入VS的。
Michael Maddox


1

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

例如,我喜欢使用框架提供的“ 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) {}
}

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

格雷格

By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.