If you look at XContainer.Add(object content) method you can see that id does not require content
to be not null.
It just does nothing in case of null.
However List.AddRange(IEnumerable collection) requires instance and throws ArgumentNullException
otherwise. Here author of the code decided that exception was more appropriate than silence.
They could implement it like:
bool List<T>.AddRange(IEnumerable<T> collection)
and return true only if collection was not empty…But they didn’t.
Quite often I ask myself whether to throw or just do nothing in case of bad parameters. The cue available for me is the question: “Can exception help the client of my function to detect logic mistake and unexpected program state?”.
If I answer to myself: “Yes, it can in MOST of use cases” then I adhere to throwing.
Nonetheless, sometimes the best way is not very evident to me. It’s a bit uncomfortable not to have strong arguments for favoring one approach over the other.
I will appreciate any sound recommendations for selecting between these alternatives.
1
The cue available for me is the question: “Can exception help the client of my function to detect logic mistake and unexpected program state?”.
And for me it’s “Is it fine for me to potentially crash my caller’s application in the most horrible way possible due to this error?”. (After the requisite “Is there any way I can avoid needing to do this check in the first place?”)
Different people have different tastes, and even different applications have different needs – hence the variety of behaviors.
In general, I like throwing early and often for things that are clearly errors. Explosive errors are easily spotted, and if the explosion is near the cause it’s easy to diagnose. I’d personally be fine with AddRange(null)
being a no-op, and will do that sort of thing for scenarios with sane behaviors that are likely caused by laziness rather than accident.