当属性不能为空时使用什么异常类型? [英] What exception type to use when a property cannot be null?

查看:437
本文介绍了当属性不能为空时使用什么异常类型?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在我的应用程序中,如果特定类的属性为空或为空(如果是字符串),则需要抛出异常。我不知道在这种情况下使用最好的例外是什么。我会讨厌创建一个新的异常,我不知道在这种情况下ArgumentNullException是否适合。

In my application I need to throw an exception if a property of a specific class is null or empty (in case it's a string). I'm not sure what is the best exception to use in this case. I would hate to create a new exception and I'm not sure if ArgumentNullException is appropriate in this case.

我应该创建一个新的异常,还是有一个异常我可以使用

Should I create a new exception or there's an exception I can use?

我不介意抛出一个ApplicationException。

I don't mind to throw an ApplicationException.

推荐答案

MSDN的标准例外指南状态:


将属性
setters的隐含值参数的名称用作值。 strong>

Do use value for the name of the implicit value parameter of property setters.

以下代码示例显示
属性,如果调用者通过空参数
,则抛出异常。

The following code example shows a property that throws an exception if the caller passes a null argument.

public IPAddress Address
{
    get
    {
        return address;
    }
    set
    {
        if(value == null)
        {
            throw new ArgumentNullException("value");
        }
        address = value;
    }
}


此外, MSDN属性设计指南说:


避免从
属性getters抛出异常。

属性getter应该是简单的
操作,没有任何前提条件。
如果一个getter可能会抛出异常,
会考虑将该属性重新设计为
作为一种方法。这个建议是
不适用于索引器。索引器可以
抛出异常,因为
参数无效。

Property getters should be simple operations without any preconditions. If a getter might throw an exception, consider redesigning the property to be a method. This recommendation does not apply to indexers. Indexers can throw exceptions because of invalid arguments.

从属性设置器中抛出
异常是有效和可接受的。 / p>

It is valid and acceptable to throw exceptions from a property setter.

所以在 null 在setter中抛出 ArgumentNullException / code>和 ArgumentException 在空字符串,并且在getter中什么也不做。由于设置器抛出,只有您可以访问支持字段,因此很容易确保它不会包含无效值。吸烟者的投掷是毫无意义的。但这可能是使用 Debug.Assert

So throw ArgumentNullException in the setter on null, and ArgumentException on the empty string, and do nothing in the getter. Since the setter throws and only you have access to the backing field, it's easy to make sure it won't contain an invalid value. Having the getter throw is then pointless. This might however be a good spot to use Debug.Assert.

如果您真的不能提供适当的默认值,那么我想你有三个选项:

If you really can't provide an appropriate default, then I suppose you have three options:


  1. 只需返回属性中的任何内容,并将此行为记录为使用合同的一部分。让来电者处理它。您可能还要求构造函数中的有效值。这可能完全不适合您的应用程序。

  1. Just return whatever is in the property and document this behaviour as part of the usage contract. Let the caller deal with it. You might also demand a valid value in the constructor. This might be completely inappropriate for your application though.

通过方法替换属性:传递无效值时抛出的setter方法,以及getter方法当属性从未分配有效值时,抛出 InvalidOperationException

Replace the property by methods: A setter method that throws when passed an invalid value, and a getter method that throws InvalidOperationException when the property was never assigned a valid value.

从getter抛出 InvalidOperationException ,因为您可以考虑财产从未被分配无效州。虽然你不应该通常从吸烟者那里扔,我想这可能是一个例外的一个很好的理由。

Throw InvalidOperationException from the getter, as you could consider 'property has never been assigned' an invalid state. While you shouldn't normally throw from getters, I suppose this might be a good reason to make an exception.

如果选择选项2或3,您还应该包含一个TryGet方法,返回一个 bool ,它指示属性是否已设置为有效值,如果返回该值位于 out 参数中。否则,您强制调用者准备处理 InvalidOperationException ,除非他们以前已经设置了属性,因此知道它不会抛出。比较 int.Parse int.TryParse

If you choose options 2 or 3, you should also include a TryGet- method that returns a bool which indicates if the property has been set to a valid value, and if so returns that value in an out parameter. Otherwise you force callers to be prepared to handle an InvalidOperationException, unless they have previously set the property themselves and thus know it won't throw. Compare int.Parse versus int.TryParse.

我建议使用TryGet方法的选项2。它不违反任何准则,对呼叫代码施加最低要求。

I'd suggest using option 2 with the TryGet method. It doesn't violate any guidelines and imposes minimal requirements on the calling code.

关于其他建议

ApplicationException 是一般的方式。 ArgumentException 对于 null 来说有点太通用了,否则的话。 > MSDN文档再次

About the other suggestions
ApplicationException is way too general. ArgumentException is a bit too general for null, but fine otherwise. MSDN docs again:


抛出适合
的最具体(最导入)的异常。例如,如果一个方法
收到一个null(Not $ in Visual
Basic)参数,它应该抛出
System.ArgumentNullException,而不是
的基本类型
System。 ArgumentException。

其实你不应该使用 ApplicationException docs ) :

In fact you shouldn't use ApplicationException at all (docs):


从T:System.Exception类而不是T:System.ApplicationException类派生自定义异常。 strong>

Do derive custom exceptions from the T:System.Exception class rather than the T:System.ApplicationException class.

原来以为自定义异常应该从ApplicationException类派生出来;然而,这还没有被发现增加重要的价值。有关详细信息,请参阅处理异常的最佳做法。

It was originally thought that custom exceptions should derive from the ApplicationException class; however, this has not been found to add significant value. For more information, see Best Practices for Handling Exceptions.

InvalidOperationException 不是因为某个方法或属性的参数无效,而是当整个操作整体无效时( docs )。不应该从设置器中抛出:

InvalidOperationException is intended not for when the arguments to a method or property are invalid, but for when the operation as a whole is invalid (docs). It should not be thrown from the setter:


如果处于不适当的状态,请抛出System.InvalidOperationException异常。如果属性集或方法调用不适用于给定对象的当前状态,则应引发System.InvalidOperationException。例如,写入已经打开读取的System.IO.FileStream应该抛出一个System.InvalidOperationException异常。

顺便说一下, InvalidOperationException 是针对对象当前状态的操作无效 如果整个课程的操作总是无效的,那么应使用 NotSupportedException

Incidentally, InvalidOperationException is for when the operation is invalid for the object's current state. If the operation is always invalid for the entire class, you should use NotSupportedException.

这篇关于当属性不能为空时使用什么异常类型?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆