在扩展方法中处理null

时间:2013-05-16 15:48:53

标签: c# extension-methods

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

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

我只是想知道在这里处理空值的最优雅方法是什么?在这些情况下是否存在典型模式,例如,如果传入null,则返回null值?看来,因为我在这里扩展字符串类,我可能想要允许空值而不抛出争论异常(因为我在使用它时并没有真正传递争论......)?但是有些人可能会说我应该像普通的方法那样抛出异常。你在这里使用的最佳做法是什么?

谢谢!

4 个答案:

答案 0 :(得分:9)

您可以遵循最小惊喜的原则:使用在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);
}

您可以使用方法proposed by Jon Skeet。它会简化为

input.ThrowIfNull("input");

Jon也有一个很好的部分 10.2.4在 C#深度中调用空引用的方法,引用:

  

检查空白作为一名尽职尽责的开发人员,我确信你的   生产方法总是先检查其论证的有效性   诉讼。这个奇怪的问题自然而然地产生了一个问题   扩展方法的特性是第一个抛出的异常   参数为null(假设它并不意味着)。应该是吗?   ArgumentNullException,好像它是一个普通的参数,或应该是它   是NullReferenceException,这是如果发生的那样   扩展方法一直是一个实例方法入手?一世   推荐前者:它仍然是一个论据,即使是扩展名   方法语法没有那么明显。

我将此推荐视为(并且根据我的个人经验):检查null是否更好,特别是对于静态方法,并且不依赖于空值。只有在您的方法的确切目的时才会例外,例如ThrowIfNullIsNullOrEmpty扩展方法。

答案 1 :(得分:1)

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

考虑使用内置的XML Documentation Comments来传达预期的行为。

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

有关许多示例,请参阅MSDN文档:

答案 2 :(得分:1)

假设我有这个:

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 - 所以最好这样做。

答案 3 :(得分:1)

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

public static bool IsInValid(this string s)         {             return(s == null)|| (s.Length == 0);         }

在您想检查时使用......

此外,您可以在任何地方使用此扩展程序