MSDN guidelines for standard exceptions 声明:
属性的隐含值参数的名称一定要使用value
二传手。
以下代码示例显示了一个
抛出异常的属性,如果
调用者传递一个空参数。
public IPAddress Address
{
get
{
return address;
}
set
{
if(value == null)
{
throw new ArgumentNullException("value");
}
address = value;
}
}
另外,MSDN guidelines for property design 说:
避免从
属性获取器。
属性获取器应该很简单
没有任何先决条件的操作。
如果 getter 可能抛出异常,
考虑重新设计该物业
成为一种方法。这个建议确实
不适用于索引器。索引器可以
由于无效而抛出异常
论据。
抛出是有效且可接受的
属性设置器的异常。
所以在null 的setter 中抛出ArgumentNullException,在空字符串上抛出ArgumentException,在getter 中什么也不做。由于 setter 抛出并且只有您可以访问支持字段,因此很容易确保它不会包含无效值。让 getter throw 是没有意义的。不过,这可能是使用Debug.Assert 的好地方。
如果你真的不能提供合适的默认值,那么我想你有三个选择:
只需返回属性中的任何内容并将此行为记录为使用合同的一部分。让调用者处理它。您可能还需要构造函数中的有效值。不过,这可能完全不适合您的应用程序。
用方法替换属性:一个 setter 方法在传递一个无效值时抛出,一个 getter 方法在该属性从未被分配一个有效值时抛出 InvalidOperationException。
从 getter 中抛出 InvalidOperationException,因为您可以将“从未分配过属性”视为无效状态。虽然您通常不应该从 getter 中抛出异常,但我想这可能是一个很好的例外处理理由。
如果您选择选项 2 或 3,您还应该包含一个 TryGet- 方法,该方法返回一个 bool,指示该属性是否已设置为有效值,如果是,则在 out 参数中返回该值.否则,您会强制调用者准备好处理InvalidOperationException,除非他们之前自己设置了属性,因此知道它不会抛出。比较 int.Parse 与 int.TryParse。
我建议将选项 2 与 TryGet 方法一起使用。它不违反任何准则,并且对调用代码的要求最低。
关于其他建议
ApplicationException 太笼统了。 ArgumentException 对于null 来说有点太笼统了,但其他方面都很好。 MSDN docs again:
一定要抛出最具体(最衍生)的异常,即
合适的。例如,如果一个方法
收到一个空值(Visual 中没有
基本)参数,它应该抛出
System.ArgumentNullException 改为
其基本类型
System.ArgumentException。
事实上你根本不应该使用ApplicationException (docs):
一定要从 T:System.Exception 类而不是 T:System.ApplicationException 类派生自定义异常。
最初认为自定义异常应该派生自 ApplicationException 类;但是,尚未发现这会增加显着的价值。有关详细信息,请参阅处理异常的最佳实践。
InvalidOperationException 不是用于方法或属性的参数无效的情况,而是用于整个操作 无效的情况 (docs)。它不应该从 setter 中抛出:
如果处于不适当的状态,请抛出 System.InvalidOperationException 异常。如果给定对象的当前状态,属性集或方法调用不合适,则应引发 System.InvalidOperationException。例如,写入已打开以供读取的 System.IO.FileStream 应引发 System.InvalidOperationException 异常。
顺便说一句,InvalidOperationException 是用于当操作无效时对象的当前状态。如果操作对于整个类总是无效,则应使用NotSupportedException。