在我的应用程序中,如果特定类的属性为null或为空(如果它是一个字符串),我需要抛出异常.我不确定在这种情况下使用的最佳例外是什么.我不想创建一个新的异常,我不确定ArgumentNullException在这种情况下是否合适.
我应该创建一个新的例外还是我可以使用的例外?
我不介意抛出一个ApplicationException.
标准异常的MSDN指南规定:
请使用值作为属性setter的隐式值参数的名称.
下面的代码示例显示了一个属性,如果调用者传递null参数,则该属性会抛出异常.
public IPAddress Address { get { return address; } set { if(value == null) { throw new ArgumentNullException("value"); } address = value; } }
此外,MSDN的财产设计指南说:
避免从属性getter中抛出异常.
属性getter应该是简单的操作,没有任何先决条件.如果getter可能抛出异常,请考虑将该属性重新设计为方法.此建议不适用于索引器.由于参数无效,索引器可能会抛出异常.
从属性设置器中抛出异常是有效且可接受的.
所以抛出ArgumentNullException
setter on null
和ArgumentException
空字符串,在getter中什么也不做.由于setter抛出并且只有您可以访问支持字段,因此很容易确保它不包含无效值.获得吸气剂是没有意义的.然而,这可能是一个好用的地方Debug.Assert
.
如果你真的无法提供适当的默认值,那么我想你有三个选择:
只需返回属性中的任何内容,并将此行为记录为使用合同的一部分.让呼叫者处理它.您可能还需要构造函数中的有效值.这可能完全不适合您的应用程序.
通过方法替换属性:在传递无效值时抛出的setter方法,以及InvalidOperationException
从未为属性分配有效值时抛出的getter方法.
InvalidOperationException
从吸气剂中扔出来,因为你可以认为"财产从未被指定为"无效状态.虽然你通常不应该从getter中抛出,但我想这可能是做出异常的一个很好的理由.
如果选择选项2或3,则还应包括一个TryGet-方法,bool
该方法返回一个指示属性是否已设置为有效值的方法,如果是,则返回out
参数中的该值.否则你强制调用者准备处理一个InvalidOperationException
,除非他们先前已经设置了属性,因此知道它不会抛出.比较int.Parse
与int.TryParse
.
我建议在TryGet方法中使用选项2.它不违反任何准则,并对调用代码施加最低要求.
关于其他建议
ApplicationException
太笼统了.ArgumentException
有点过于笼统null
,但除此之外.MSDN再次提供文档:
抛出最合适的(最派生的)异常.例如,如果方法接收null(在Visual Basic中为Nothing)参数,则应抛出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
.