Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Handling null in extension method

I have a simple extension method for string class which will strip all non numeric characters from a string. So if I have a string like for example a phone number such as "(555) 215-4444" it will convert it to "5552154444". It looks like this:

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

I am just wondering what is the most elegant way to handle a null value here? Is there a typical pattern to follow in these cases, such as return back a null value if a null is passed in? It seems since I'm extending the string class here I may want to allow null values and not throw a arguement exception (since I'm not really passing in an arguement when I use this...) ? But some might argue I should throw an exception like a 'normal' method would. What's the best practice you are using here?

Thanks!

like image 521
dferraro Avatar asked May 16 '13 15:05

dferraro


4 Answers

You can follow the principle of least surprise: use pattern implemented in 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);
}

You can use method, proposed by Jon Skeet. It will reduce your check simply to

input.ThrowIfNull("input");

Also Jon has a good section 10.2.4 Calling a method on a null reference in C# in Depth, quote:

CHECKING FOR NULLITY As a conscientious developer, I’m sure that your production methods always check their arguments’ validity before proceeding. One question that naturally arises from this quirky feature of extension methods is what exception to throw when the first argument is null (assuming it’s not meant to be). Should it be ArgumentNullException, as if it were a normal argument, or should it be NullReferenceException, which is what would’ve happened if the extension method had been an instance method to start with? I recommend the former: it’s still an argument, even if the extension method syntax doesn’t make that obvious.

I see this recommendation as (and from my personal experience): it's always better to check for null, specially for static methods and do not to rely on null values. One exception only if it is the exact purpose of your method, for example ThrowIfNull or IsNullOrEmpty extension methods.

like image 83
Ilya Ivanov Avatar answered Oct 14 '22 02:10

Ilya Ivanov


It doesn't really matter as long as you communicate the behavior well (so that the end-user knows what to expect).

Consider using the built-in XML Documentation Comments to communicate expected behavior.

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

See MSDN documentation for many examples:

like image 41
JDB Avatar answered Oct 14 '22 03:10

JDB


Suppose I have this:

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

If I then run the following code, what happens?

A a = null;
a.F();

You get a NullReferenceException. So I would say the proper way to write an equivalent extension method would be as follows.

class A
{
}

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

However, .NET disagrees with me on this. The standard in .NET is to instead throw an ArgumentException - so it's probably best to do that instead.

like image 1
Timothy Shields Avatar answered Oct 14 '22 04:10

Timothy Shields


Simple ; Create another method for String , say IsInValid()

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

use whereever you wanna check...

Furthermore, you can use this extension anywhere

like image 1
Dhanasekar Avatar answered Oct 14 '22 02:10

Dhanasekar