在扩展方法中处理null

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

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

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

谢谢!

您可以遵循最少惊喜的原则:使用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时抛出的exception(假设它不是意图)。 它应该是ArgumentNullException,就好像它是一个普通的参数,或者它应该是NullReferenceException,如果扩展方法是一个开始的实例方法,这会发生什么? 我推荐前者:它仍然是一个参数,即使扩展方法语法没有那么明显。

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

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

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

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

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

  • DateTime.ParseExact方法(String,String,IFormatProvider)
  • Uri.FromHex方法

假设我有这个:

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

如果我然后运行以下代码,会发生什么?

 A a = null; aF(); 

你得到一个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(this string s){return(s == null)|| (s.Length == 0); }

使用你想检查…

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