关于异常的问题已经有很多问题了,但我找不到能回答我问题的问题。如果我错过了,请随意指出另一个问题的方向。
我的问题很简单:其他(C#)开发人员如何选择最合适的异常类型?之前我写过以下代码:
if (Enum.IsDefined(enumType, value))
{
return (T)Enum.Parse(enumType, value);
}
else
{
throw new ArgumentException(string.Format("Parameter for value \"{0}\" is not defined in {1}", value, enumType));
}
我已经意识到,如果当时我知道它的存在,抛出InvalidEnumArgumentException
可能会更合适。
是否有可用的权威资源可以帮助开发人员选择异常类型,还是仅仅是经验问题?
我已经向Noldorin提出了一些观点,即在一个经过深思熟虑的答案中提供一系列想法。这些要点可能真的让你们中的任何一个 - 感谢所有的建议。
答案 0 :(得分:12)
Krzysztof Cwalina在see chapter "1.1.1 Choosing the Right Type of Exception to Throw"
上发表了一篇好文章PS考虑订阅他的博客。好好阅读!
回答你的问题: InvalidEnumArgumentException
因为抛出最有意义(最有派生的)异常是有意义的。
AND捕获ArgumentException的调用者,也捕获InvalidEnumArgumentException ...
答案 1 :(得分:9)
我会说这只是体验。我经常发现新的异常,而且我已经在.NET的许多方面工作了一段时间了!无论如何,你想要这个消息来源告诉你什么?选择适当的异常类型似乎是高度特定于上下文的,所以我对它可以提供的建议水平表示怀疑。列出更常见的那些将是它可以提供的最多。异常类型的名称和Intellisense描述通常很清楚地解释了它们的使用场景。
我的建议只是让自己熟悉所有基本的(特别是System
,System.IO
中的那些,以及您经常使用的任何其他命名空间),并在此过程中学习其他命名空间。我发现我通常只使用一小部分就可以逃脱。如果您在BCL中已经存在更具体的异常时意外使用了更通用的异常类型,那么它就不是很大的罪行,并且可以在以后轻松更改。说实话,对于任何特别具体的错误,您通常需要创建自己的继承自Exception
的类。
希望有所帮助。
修改:如果您想了解常见的简要指南,请参阅MSDN上的Common Exception Classes页面。
答案 2 :(得分:4)
Common Exception Types and their Explanations
我认为这可能会帮助您找出最合适的例外情况。如果需要,您还可以查看MSDN文档以获取有关Exception类及其所有类型的更多信息。
答案 3 :(得分:3)
如果您查看MSDN article on System.Exception,则页面底部会显示继承Exception的BCL异常类型的完整列表。它不是一个关于什么应该用于什么的确定列表 - 但它确实为你提供了一个开始检查异常类型的好地方。通过每个将告诉你它们应该用于什么:
还有一篇关于.NET异常层次结构的相当全面的文章:
事实上,MSDN库中有关处理和抛出异常的整个部分非常好:
答案 4 :(得分:2)
我认为真正的问题是问自己“我想要处理什么类型的例外?”如果您不打算对InvalidEnumArgumentException或ArgumentException进行特殊处理,那么它们就没有优于普通旧Exception的优势。
我通常会抛出异常或将异常包装在自定义异常中。
编辑添加: 有一次,我记得微软的指导是你的应用程序永远不应该抛出框架异常,而应该只抛出ApplicationException的扩展。
答案 5 :(得分:1)
我通常定义自己的异常结构,首先创建一些基本异常:
class MyProjectNameException:Exception
{
...constructors, etc
}
然后派生类以获得更精确的异常。通过这种方式,您可以确切地知道何时可以预期哪个异常,并且您知道异常是由您还是由框架引发的。
答案 6 :(得分:1)
我的大多数常见例外都写在我桌面上的明信片上,并在人们试图以特殊的方式与我互动时使用它们。
这对于确定最适合哪种异常是非常好的做法......
我发现自己主要使用的是 OperationNotSupportedException
答案 7 :(得分:1)
如果您发现一个非常合适的例外,您可以使用它。
如果有疑问,请使用ApplicationException
。这是一个例外,适用于不属于标准库的代码。
如果异常不打算以标准化方式使用(比如捕获基类IOException
以捕获任何与I / O相关的错误),那么您在异常中添加的消息比异常的类型。