我想我知道我的意思,但我不太确定......
框架文档将类型总结如下:
当方法调用对于对象的当前状态无效时引发的异常。
有一些明确的情况,想到的一种情况是操作需要打开的数据库,但尚未使用所需的信息初始化对象以连接到数据库。
(相切:另一方面,ADO.NET 还要求您显式打开连接的行为并不那么明确;DataAdapter 通过简单地打开连接来偏离这一点,当且仅当它关闭时再次关闭它入口, 我发现这很方便, 并为自己制作了一个使用此模式的 ADO.NET 包装器. 当然这意味着我冒着执行 2 ExecuteNonQuery 并不必要地返回到池的连接, 但我仍然可以打开和关闭我想要的连接和这种性能损失与获得异常相比微不足道。)
我想我的问题的答案是,只有在这种明确的情况下,我们才应该抛出异常。但是在以下情况下哪种异常类型最合适:
public class FormatterMapping
{
Dictionary formattersByName = new ...();
public IFormatter GetFormatter(string key)
{
IFormatter f;
if (formattersByName.TryGetValue(key, out f))
return f;
else
throw new ??Exception("explanation of why this failed.");
}
}
我的第一反应是抛出 ArgumentException。然后我开始认为映射缺少键也可能是参数“错误”。基本上“获取格式化程序 X”操作是无效的,因为X 不在映射中,但我真的不知道 X 是否“应该在那里”或者在这里询问 X 是不明智的。
我当然可以通过返回 null 来绕过整个问题,但这会打开一个更大、更深的蠕虫罐。没有办法知道什么时候会使用返回值,所以后来发生 NullReferenceException 的代码可能与出错的地方没有明显的关系。要么是映射设置不当,要么是使用它的代码要求了一些不应该的东西。
躲避这个问题的另一种方法是使用 TryGetFormatter 选项,但我打算使用此选项的方式实际上应该让调用者知道映射中的内容和不存在的内容,因此在用户代码上强制使用此模式不是也不好。
请不要回答我应该抛出ApplicationException!无论您认为代码应该做什么,请提供原因。毕竟,这里真正有问题的是推理。
除非有人说服我,否则我倾向于 ArgumentException。从映射的角度来看,这个论点是错误的,所以至少有一个明确的推理支持这一点。:)