I came across this MSDN page that states:
Do not throw Exception, SystemException, NullReferenceException, or IndexOutOfRangeException intentionally f
I suspect the intent with the last 2 is to prevent confusion with inbuilt exceptions that have an expected meaning. However, I'm of the opinion that if you are preserving the exact intent of the exception: it is the correct one to throw. For example, if you are writing a custom collection, it seems entirely reasonable to use IndexOutOfRangeException - clearer and more specific, IMO, than ArgumentOutOfRangeException. And while List might choose the latter, there are at least 41 places (courtesy of reflector) in the BCL (not including arrays) that throw bespoke IndexOutOfRangeException - none of which are "low level" enough to deserve special exemption. So yeah, I think you can justly argue that that guideline is silly. Likewise, NullReferenceException is kinda useful in extension methods - if you want to preserve the semantic that:
obj.SomeMethod(); // this is actually an extension method
throws a NullReferenceException when obj is null.