C# 仅涉及消息时是否应使用自定义异常?

C# 仅涉及消息时是否应使用自定义异常?,c#,exception,C#,Exception,我见过许多创建自定义异常的情况,其中只使用了3个标准构造函数重写,没有额外的信息 在这些情况下,我建议使用InvalidOperationException,因为实际上没有调用程序捕获这些自定义异常 例如,在switch语句的默认块中使用: public InvalidSwitchValueException() : base() { } public InvalidSwitchValueException(string message)

我见过许多创建自定义异常的情况,其中只使用了3个标准构造函数重写,没有额外的信息

在这些情况下,我建议使用InvalidOperationException,因为实际上没有调用程序捕获这些自定义异常

例如,在switch语句的默认块中使用:

public InvalidSwitchValueException()
            : base() { }

        public InvalidSwitchValueException(string message)
            : base(message) { }

        public InvalidSwitchValueException(string message, Exception innerException)
            : base(message, innerException) { }

你推荐什么?

视情况而定。如果您打算这样使用它:

try
{
}
catch (InvalidSwitchValueException)
{
    // handle this special case differently
}
catch (Exception)
{
}
它比:

try
{
}
catch (Exception e)
{
    if (e.Message == "Check the message")
    {
        // handle this special case differently
    }
}
如果它只是有一个不同的类型,而不打算在任何地方捕捉它,那么它就看不出有什么意义。如果您这样做,它将提高您的代码质量。想想如果您有多语言错误消息(就像.NET本身一样),会发生什么您不能也不应该依赖此消息!从来没有

在评论中也提出了一个很好的观点:

这是一个永远都不应该被捕获的异常,因为它表明调用方中存在一个应该修复的bug吗?如果是这样,那么设计异常以使bug易于发现和修复,而不是设计异常以便于捕获


命名异常非常有用的一点是,如果抛出异常,则更容易找到它们。举个例子:
NullReferenceException
是最糟糕的,因为(没有调用堆栈)它绝对不能帮助您分析问题。检查并抛出一个类型化异常,如
catdidntfindmouseeexception
,可以为您提供一个起点,也可能是一个实际出错的线索。

它有助于只捕获正确类型的异常。通常创建异常是为了允许调用方采取特定的操作(如果只有“invalidooperationexception”,则无法知道该操作)为调用方提供一种确定如何从异常中恢复的方法是一种良好的设计实践。(在当今世界,人们应该不惜一切代价避免“应用程序自杀”)有4个标准构造函数。@SriramSakthivel:如果超出范围的值确实是一个参数,那么至少.@O.R.Mapper在这里是重要的;这是一个永远不应该被捕获的异常,因为它表明调用方中有一个应该修复的错误吗?如果是这样,那么设计该异常以使该错误易于查找和修复,而不是而不是将异常设计为易于捕获。注意,如果您使用的是.NET内置异常,请仔细检查
e.Message==“Something”
。根据您将操作系统设置为何种语言,消息会有所不同。(但有时你必须这样做,而且没有公开的参数可以检查以查找你需要的信息,我正在查看你的
SqlException
)@ScottChamberlain:对不起,这对我来说是显而易见的。将会更新。@EricLippert:我在我的答案中加入了你的评论。添加的文本是否反映了你的观点?