Yes, there are good reasons:
- It pinpoints what is null, which may not be obvious from a
NullReferenceException - This causes the code to crash on invalid input, even if some other condition means the value is not dereferenced
- This makes an exception before the method can have any other side effects that you might have reached before the first dereference
- This means that you can be sure that if you pass the parameter to something else, you will not break their contract.
- It documents your method requirements (using Code Contracts for this, of course, is even better)
Now about your objections:
- This is slower: did you find that this is actually a bottleneck in your code, or do you guess? Profanity checks are very quick, and in the vast majority of cases they will not become a bottleneck.
- This makes the code harder to maintain: I think the opposite. I think itβs easier to use the code where it made it clear whether the parameter can be zero, and where you are sure that this condition is met.
And for your statement:
Obviously, code that uses s will throw an exception anyway.
Really? Consider:
void f(SomeType s) {
This uses s but does not raise an exception. If it is not valid for s as null, and this indicates that something is wrong, an exception is the most appropriate behavior here.
Now that you put these argument validation checks, that's another matter. You can trust all the code in your class, so don't worry about private methods. You can trust the rest of your assembly so you don't have to worry about internal methods. You should almost certainly check the arguments for public methods.
Note: the one-parameter overload of the ArgumentNullException constructor should be just a parameter name, so your test should be:
if (s == null) { throw new ArgumentNullException("s"); }
Alternatively, you can create an extension method that allows some patience:
s.ThrowIfNull("s");
In my version of the extension method (generic), I return the original value if it is not null, which allows me to write things like:
this.name = name.ThrowIfNull("name");
You can also have an overload that does not accept the parameter name if you are not too worried about it.
Jon Skeet Sep 28 2018-11-11T00: 00Z
source share