在扩展方法中处理null

本文关键字:处理 null 方法 扩展 | 更新日期: 2023-09-27 18:13:51

我有一个简单的字符串类的扩展方法,它将从字符串中剥离所有非数字字符。因此,如果我有一个字符串,例如一个电话号码,如"(555)215-4444",它会将其转换为"5552154444"。它看起来像这样:

public static string ToDigitsOnly(this string input)
{
    Regex digitsOnly = new Regex(@"[^'d]");
    return digitsOnly.Replace(input, String.Empty);
}

我只是想知道什么是最优雅的方式来处理null值在这里?在这些情况下,是否有一个典型的模式可以遵循,例如,如果传入一个空值,则返回一个空值?似乎因为我在这里扩展字符串类,我可能想要允许空值,而不是抛出一个参数异常(因为我不是真的在传递一个参数,当我使用这个…)?但是有些人可能会争辩说我应该像"正常"方法那样抛出异常。你在这里使用的最佳实践是什么?

谢谢!

在扩展方法中处理null

您可以遵循最小意外原则:使用在LINQ中实现的模式:

public static string ToDigitsOnly(this string input)
{
    if(input == null)
          throw new ArgumentNullException("input");
    Regex digitsOnly = new Regex(@"[^'d]");
    return digitsOnly.Replace(input, String.Empty);
}

你可以使用方法,由Jon Skeet提出。它将把你的支票减到

input.ThrowIfNull("input");

Jon也有一个很好的章节10.2.4在 c#深度中调用null引用的方法,引用:

检查null作为一个有责任心的开发人员,我确信您的生产方法总是先检查其参数的有效性继续。一个问题自然会从这个离奇事件中产生扩展方法的特性是在第一次调用时抛出什么异常参数为空(假设它不是故意的)。应该是吗?ArgumentNullException,就好像它是一个普通的参数,或者应该是是NullReferenceException,如果扩展方法已经是一个实例方法开始?我推荐前者:它仍然是一个论点,即使扩展方法语法没有明确说明。

我认为这个建议是(从我个人的经验来看):检查null总是更好的,特别是对于静态方法,不要依赖于null值。一个例外只有当它是你的方法的确切目的,例如ThrowIfNullIsNullOrEmpty扩展方法。

只要你很好地传达了行为(这样最终用户就知道会发生什么),这并不重要。

考虑使用内置的XML文档注释来传达预期的行为。

/// <exception cref="ArgumentNullException">argument is null.</exception>
public string Example( string argument )
{
    if ( argument == null )
        throw new ArgumentNullException();
    return argument.ToString();
}

查看MSDN文档了解更多示例:

  • DateTime。解析方法(String, String, IFormatProvider)
  • Uri。FromHex方法

假设我有这个:

class A
{
    public void F()
    {
        //do stuff
    }
}

如果我运行下面的代码,会发生什么?

A a = null;
a.F();

你得到一个NullReferenceException。因此,我认为编写等效扩展方法的正确方法如下:

class A
{
}
static class AExtensions
{
    void F(this A a)
    {
        if (a == null)
        {
            throw new NullReferenceException();
        }
        //do stuff
    }
}

然而,. net不同意我的观点。. net的标准是抛出一个ArgumentException——所以最好这样做。

简单;为String创建另一个方法,输入IsInValid()

public static bool IsInValid(此字符串无效){return (s == null) || (s == 0);}

在任何你想检查的地方使用

此外,你可以在任何地方使用这个扩展