If I need to throw an exception from within my application which of the built-in .NET exception classes can I use? Are they all fair game? When should I derive my own?
My advice would be to focus on two things:
In otherwords, I would sit down and identify:
The answer to #1 is, of course, application specific. The answer to #2 is "what ever similar code they are already familiar with does".
The behavior that comes out of this is:
Under the scenarios that arise in your programs that also arrive inside the framework, such as arguments being null, out of range, being invalid, methods not being implemented, or just not supported, then you should use the same exceptions the framework uses. The people using your APIs are going to expect that they behave that way (because that's how everything else behaves), and so will be better able to use your api from the "get go".
a. The primary purpose of an exception is for human communication. They convey information about something that happened that shouldn't have. They should provide enough information to identify the cause of a problem and to figure out how to resolve it.
b. Internal consistency is extremely important. Making your app behave as universally as possible under similar circumstances will make you API's users more productive.
As far as there being hard and fast rules about what you should and should not do... I wouldn't worry about that stuff. Instead I would just focus on identifying scenarios, finding the existing exception that fits those scenarios, and then carefully desining your own if an existing one doesn't exist.