One pattern I’ve started running into is developers explicitly throwing a NullReferenceException when validating the “this” parameter of an extension method.
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action) { if (null == enumerable) { throw new NullReferenceException(); } // rest omitted }
The desired behavior here is to make extension methods look even more like instance methods by adding similar exception semantics. So now a call to col.ForEach(..) throws a NullReferenceException if col is null just like it would if ForEach were a real method.
However this is incorrect and should be avoided.
For me #1 and #3 are the most compelling points. Violating either of these goes against established practices and semantic and leads to incorrect behavior in programs.
The correct pattern here is that for a normal static method: use an ArgumentNullException.
public static void ForEach<T>(this IEnumerable<T> enumerable, Action<T> action) { if (null == enumerable) { throw new ArgumentNullException(); } // rest ommitted }
[1] I very much wish explicitly throwing runtime exceptions produced unverifiable code
[2] Whether or not this is a good idea is a different question