11

Well, a few months ago I asked a similar question about C and C++, but I've been paying more attention to C# lately due to the whole "Windows Phone" thing.

So, in C#, should one bother to check against NULL at method boundaries? I think this is different than in C and C++, because in C# one generally can determine whether a given reference is valid -- the compiler will prevent one from passing uninitialized references anywhere, and therefore the only remaining possible mistake is for it to be null. Furthermore, there's a specific exception defined inside the .NET Framework for these things, the ArgumentNullException, which seems to codify what programmers think they should be getting when an invalid null was passed.

My personal opinion is once again that a caller doing this is broken, and that said caller should have NREs thrown at them until the end of days. However, I'm much less sure about this than I am in native code land -- C# has quite a different programming style in places compared to either C or C++ in this regard.

So... should you check for null parameters in C# methods?

Community
  • 1
  • 1
Billy ONeal
  • 104,103
  • 58
  • 317
  • 552

4 Answers4

8

Yes, check for them. Preferably use Code Contracts to tell the caller that you require non-null parameters

void Foo(Bar bar) {
    Contract.Requires(bar != null);
}

This is particularly advantageous since the client can see exactly what is required of parameters.

If you can't use Code Contracts, use a guard clause

void Foo(Bar bar) {
    Guard.Against<ArgumentNullException>(bar == null);
}

Fail fast.

jason
  • 236,483
  • 35
  • 423
  • 525
  • will `Contract.Requires(bar != null);` flag `Foo(null);` at compile time which I doubt it will in which case what is the advantage of using something like this compared to a simple null check with `if`? – Bala R May 07 '11 at 04:17
  • Where do Contract/Guard come from? I'm not familiar with those bits. :/ Does this apply to publicly exposed methods, or intra component methods as well? – Billy ONeal May 07 '11 at 04:37
  • @Bill ONeal: Code Contract is in .NET 4.0 in the `System.Diagnostics.Contracts` namespace. `Guard` is a common utility class that people have their own version of but basically it just throws the exception specified in the type parameter if the condition is satisfied. – jason May 07 '11 at 05:06
  • 2
    @Bala R: You can do static checking, and it becomes part of the documentation. – jason May 07 '11 at 05:06
  • 1
    The Contracts/Guard part distracts a little from the answer. _How_ you check depends on several factors. I like Contracts but it won't be acceptable everywhere (yet). – H H May 07 '11 at 07:50
5

I think it's better to throw an ArgumentNullException (or use a contract as Jason suggests) if your method doesn't want a particular parameter to be null. It's a much better indicator by the contract to the client not to pass null in the first place when calling your method.

Null-checking is then the client's responsibility which makes for more maintainable code on both sides (often a win-win situation)... at least that's what I feel.

Community
  • 1
  • 1
BoltClock
  • 700,868
  • 160
  • 1,392
  • 1,356
  • Do you think this is a must for exposed library methods only, or internally as well? – Billy ONeal May 07 '11 at 04:38
  • @Billy: Only do this for exposed library methods. Only methods that are marked as `public` should do parameter validation of any type. It's an unnecessary expense for internal and private methods, that's one of the reasons to have methods that aren't part of the interface in the first place. – Cody Gray - on strike May 07 '11 at 07:59
  • @Cody: What if the class itself is not exposed? E.g. the class is `internal`. – Billy ONeal May 09 '11 at 23:24
  • @Billy: That's really the same thing. The access level of the class mediates the access level of its individual members. If the class can't be used outside of the library, it's not part of it's public interface. You *might* want to implement parameter validation simply for convenience or thoroughness inside of the library, but it's not strictly necessary, as the internal code can be strictly vetted. The only problem is for classes that are going to be exposed externally, used in situations where the callers can't be vetted and tested extensively. – Cody Gray - on strike May 10 '11 at 07:57
3

It is a good practice to validate all the parameters at least in public methods. This helps to locate bugs faster and also helps while reading the code, as it describes method's contract.

We implemented a static class AssertUtilities that has a bunch of method for parameters and state validation. I believe some people call such classes Guard.

For example:

    public static void ArgumentNotNull(object argument, string argumentName)
    {
        if (argument == null)
            throw new ArgumentNullException(argumentName);
    }

    public static void ArgumentInRange(decimal argument, decimal minValue, decimal maxValue, string argumentName)
    {
        if (argument < minValue || argument > maxValue)
        {
            throw new ArgumentOutOfRangeException(
                argumentName,
                FormatUtilities.Format("Argument out of range: {0}. Must be between {1} and {2}.", argument, minValue, maxValue));
        }
    }

    public static void ArgumentState(bool expression, string argumentName, string formatText, params object[] args)
    {
        if (!expression)
            throw new ArgumentException(FormatUtilities.Format(formatText, args), argumentName);
    }

    public static void ArgumentHasText(string argument, string argumentName)
    {
        ArgumentNotNull(argument, argumentName);
        ArgumentState(argument.Length > 0, argumentName, "Argument cannot be an empty string.");
    }
Alex Aza
  • 76,499
  • 26
  • 155
  • 134
2

So... should you check for null parameters in C# methods?

Yes, unless of course when null is permitted.

A better perspective: You should always check for valid parameter values. Sometimes a reference is allowed to be null, sometimes an int must be >= 0 or a string may not be NullOrWhiteSpace.

So it is a good practice to start every method with a parameter validation block.

From there on there are a few choices. Validation on internal/private methods is usually considered less critical, and for performance reasons it can be made conditional (or even left out).

Validation at a boundary is usually left on in Release builds. There is very little reason to ever turn it off.

Most projects will use some helper classes for validation, to minimize repetitive coding inside the methods. A very good but not yet very popular toolkit is the built-in System.Diagnostics.Contracts class. The Code-Contracts tools have many settings concerning parameter validation.

H H
  • 263,252
  • 30
  • 330
  • 514
  • See, I strongly disagree for the "check for valid parameters" bit -- in general case that is not possible or practical, even in environments as restricted as the CLR. – Billy ONeal May 09 '11 at 23:22