Ho votato a favore della risposta di Josh , ma vorrei aggiungerne un'altra alla lista:
System.InvalidOperationException deve essere generato se l'argomento è valido, ma l'oggetto si trova in uno stato in cui l'argomento non deve essere utilizzato.
Aggiornamento preso da MSDN:
InvalidOperationException viene utilizzato nei casi in cui la mancata invocazione di un metodo è causata da motivi diversi dagli argomenti non validi.
Diciamo che il tuo oggetto ha un metodo PerformAction (azione enmSomeAction), enmSomeActions valide sono Open e Close. Se si chiama PerformAction (enmSomeAction.Open) due volte di seguito, la seconda chiamata dovrebbe generare InvalidOperationException (poiché l'arugment era valido, ma non per lo stato corrente del controllo)
Dato che stai già facendo la cosa giusta programmando in modo difensivo, ho un'altra eccezione da menzionare è ObjectDisposedException. Se il tuo oggetto implementa IDisposable, dovresti sempre avere una variabile di classe che tiene traccia dello stato disposto; se l'oggetto è stato eliminato e viene chiamato un metodo su di esso, è necessario aumentare ObjectDisposedException:
public void SomeMethod()
{
If (m_Disposed) {
throw new ObjectDisposedException("Object has been disposed")
}
// ... Normal execution code
}
Aggiornamento: per rispondere al tuo follow-up: è un po 'una situazione ambigua ed è resa un po' più complicata da un tipo di dati generico (non nel senso di .NET Generics) utilizzato per rappresentare un insieme specifico di dati; un enum o un altro oggetto fortemente tipizzato sarebbe un adattamento più ideale, ma non abbiamo sempre quel controllo.
Personalmente mi sporgerei verso ArgumentOutOfRangeException e fornire un messaggio che indica che i valori validi sono 1-12. Il mio ragionamento è che quando parli di mesi, supponendo che tutte le rappresentazioni intere dei mesi siano valide, ti aspetti un valore compreso tra 1 e 12. Se solo determinati mesi (come i mesi che avevano 31 giorni) fossero validi, allora non avresti a che fare con un intervallo di per sé e lancerei una ArgumentException generica che indicava i valori validi e li documenterei anche nei commenti del metodo.