.net 如果字符串为空,是否应该抛出ArgumentNullException?

.net 如果字符串为空,是否应该抛出ArgumentNullException?,.net,.net,我正在研究一个方法,该方法在给定字符串参数的情况下执行某些操作。字符串参数的有效值不是null或string.Empty。我的代码是这样的 private void SomeMethod(string someArgument) { if(string.IsNullOrEmpty(someArgument)) 抛出新ArgumentNullException(“someArguments”); //做些工作 } 没有什么太令人兴奋的。我的问题是,即使字符串等于string.Empty,也可以抛

我正在研究一个方法,该方法在给定字符串参数的情况下执行某些操作。字符串参数的有效值不是null或string.Empty。我的代码是这样的

private void SomeMethod(string someArgument)
{
if(string.IsNullOrEmpty(someArgument))
抛出新ArgumentNullException(“someArguments”);
//做些工作
}
没有什么太令人兴奋的。我的问题是,即使字符串等于string.Empty,也可以抛出ArgumentNullException吗?因为从技术上讲它不是空的。如果您认为它不应该抛出ArgumentNullException,那么应该抛出什么异常?

应该为
字符串.Empty
大小写抛出。这将指示除空值以外的问题。为了避免出现
NullReferenceException
我首先检查null,然后修剪并检查空的大小写,以防止任何空格通过

private void SomeMethod(string someArgument)
{
    if(someArgument == null)
        throw new ArgumentNullException("someArgument");

    if (someArgument.Trim() == String.Empty)
        throw new ArgumentException("Input cannot be empty", "someArgument");

    // do some work
}

从.NET 4.0开始,您可以使用
String.IsNullOrWhiteSpace
方法一次性执行这些检查。通过这样做,您放弃了指定粒度异常类型的功能,因此我会选择
ArgumentException
,并相应地更新消息。

如果空字符串不是您的方法的可接受输入,您应该抛出
ArgumentException
。如果您在客户机未提供
null
参数的情况下抛出
ArgumentNullException
,可能会让客户机非常困惑


这只是另一个用例。您也可能有不接受空输入值但接受空字符串的方法。在整个应用程序中保持一致性非常重要。

ArgumentNullException有时在.NET Framework中用于String.IsNullOrEmpty案例-例如
System.Windows.Forms.Clipboard.SetText

因此,我认为在代码中也这样做是合理的,除非在区分这两种情况时有实际价值

请注意,此异常和从ArgumentException派生的其他异常通常表示编程错误,因此需要提供帮助开发人员诊断问题所需的信息。我个人认为,如果将ArgumentNullException用于空字符串参数,开发人员不太可能会感到困惑,特别是如果您像下面的示例那样记录这种行为

/// <summary>
/// ... description of method ...
/// </summary>
/// <param name="someArgument">... description ...</param>
/// <exception cref="ArgumentNullException">someArgument is a null reference or Empty.</exception>
public void SomeMethod(string someArgument)
{
   ...
}
//
/// ... 方法说明。。。
/// 
/// ... 描述
///someArgument是空引用或空引用。
公共void SomeMethod(字符串someArgument)
{
...
}

考虑到所有已经说过的事情(乔/艾哈迈德·马格德),我会为这个案例创建一个例外

class ArgumentNullOrEmptyException : ArgumentNullException

这真的要视情况而定

问题是,这真的是一个错误吗?我的意思是,你是否总是期望有价值?如果您这样做了,那么您在这里的最佳选择可能是创建您自己的
异常
,可能是这样的:

class StringEmptyOrNullException : Exception
{
}
在这里,您还可以添加自己的构造函数和添加的信息等

但是,如果它不是程序中发生的“异常”,那么从方法返回null并从那里处理它可能是一个更好的主意。请记住,
异常
用于异常情况

希望这有帮助


凯尔

为什么不使用此代码

private void SomeMethod(string someArgument)
{
//chek only NULL
if(ReferenceEquals(someArgument,null))
    throw new ArgumentNullException("someArgument");

// and after trim and check
if (someArgument.Trim() == String.Empty)
    throw new ArgumentException("Input cannot be empty", "someArgument");

// do some work
}

这是一个老问题,但由于谷歌对它的排名很高,未来读者还有一个(更好的!)选择:
ArgumentOutOfRangeException

ArgumentException
ArgumentNullException
ArgumentOutOfRangeException
的基类。这意味着对于处理异常的开发人员来说,它更通用,信息更少。换句话说,虽然所有
ArgumentNullException
s和
ArgumentOutOfRangeException
s也都是
ArgumentException
s,但情况并非如此

ArgumentOutOfRangeException
是一个更具体的异常,它表示“您提供的值不在我期望的值范围内”,这正是您试图告诉其他开发人员的。如果您不接受空字符串,那么它是最好的标准异常类型

或者,如果区分不同的值非常重要,请创建您自己的从
ArgumentNullException
派生的异常类型


在处理您的异常时,其他不需要区分他们提供的值为何错误的开发人员可以捕获
ArgumentException
,然后一次获取所有异常。

当字符串为“”时抛出ArgumentNullException是误导性的。我同意,唉,我以前这样做的原因是因为“Joe”给出的答案,在.net framework代码中是这样使用的。我使用的是C#2.0,对InvalidArgumentException的唯一引用是在Microsoft.SqlServer.Management.Common命名空间中,是您建议的还是您建议我创建自己的InvalidArgumentException类?@Keith:您是对的,我错了。如果您愿意,您可以自己编写,也可以使用框架提供的ArgumentException。我将进行编辑以反映正确的名称。ArgumentException构造函数不接受ArgumentNullException这样的“paramName”参数。因此,“throw new ArgumentException(“paramName”)”可能会令人困惑,因为它没有给出任何参数错误的指示。您应该提供一个类似(“someArgument可能不是空字符串”)的“message”参数。在国际应用程序中,此消息需要本地化。因此,只有在确实需要区分空字符串和空字符串的情况下,我才会遇到所有这些麻烦。@Joe:在这种情况下,可能采用两个字符串参数的构造函数更合适,第一个是错误消息,第二个是导致异常的参数()。这将导致:抛出新的ArgumentEx