32

Sto implementando un'implementazione di raccolta personalizzata che può essere di sola lettura o non di sola lettura; vale a dire, tutti i metodi che modificano la raccolta chiamare una funzione che è l'equivalente morale di:Quando utilizzare InvalidOperationException o NotSupportedException?

private void ThrowIfReadOnly() { 
    if (this.isReadOnly) 
     throw new SomeException("Cannot modify a readonly collection."); 
} 

non sono sicuro che di NotSupportedException o InvalidOperationException dovrei usare in quel caso.

risposta

43

MSDN ha solo un po 'di orientamento su questo argomento preciso, il NotSupportedException:

Per gli scenari in cui a volte è possibile che l'oggetto per eseguire l'operazione richiesta, e lo stato dell'oggetto determina se l'operazione può essere eseguito, vedi InvalidOperationException.

Quello che segue è puramente la mia interpretazione della norma:

  • Se lo stato dell'oggetto può cambiare in modo che l'operazione può diventare non valida/validi durante la vita dell'oggetto, dovrebbero essere usati poi InvalidOperationException.
  • Se l'operazione è sempre non valida/valida durante l'intero ciclo di vita dell'oggetto, è necessario utilizzare NotSupportedException.
  • In tal caso, "lifetime" significa "tutto il tempo in cui chiunque può ottenere un riferimento all'oggetto" - vale a dire, anche dopo una chiamata Dispose() che spesso rende inutilizzabili la maggior parte degli altri metodi di istanza;
    • Come sottolineato da Martin Liversage, nel caso in cui un oggetto sia stato smaltito, è necessario utilizzare il tipo più specifico ObjectDisposedException. (Questo è ancora un sottotipo di InvalidOperationException).

L'applicazione pratica di dette norme in tal caso sarebbe come segue:

  • Se isReadOnly può essere impostato solo al momento in cui viene creato l'oggetto (ad esempio un parametro del costruttore), e mai in qualsiasi altro momento, quindi utilizzare NotSupportedException.
  • Se isReadOnly può cambiare durante la vita dell'oggetto, è necessario utilizzare InvalidOperationException.
    • Tuttavia, il punto di InvalidOperationException vs NotSupportedException è effettivamente discutibile nel caso di attuazione di una collezione - data la descrizione di IsReadOnly su MSDN, l'unico comportamento consentito per IsReadOnly è che il suo valore non cambia mai dopo la raccolta viene inizializzato. Il che significa che un'istanza di raccolta può essere modificabile o di sola lettura, ma dovrebbe sceglierne una in fase di inizializzazione e seguirla per il resto della sua durata.
+5

Chiamare un metodo su un oggetto eliminato dovrebbe gettare 'ObjectDisposedException' invece di' InvalidOperationException' anche se è un'operazione non valida. –

+3

@ Martin: Oh, bello! Non sapevo nulla di "ObjectDisposedException".(E come 'ObjectDisposedException' è un sottotipo di 'InvalidOperationException', si lega bene ad essere un caso particolare di' InvalidOperationException') –

+0

Che dire qualcosa come: bool SomeMethod (param) { if (param in some state A) restituisce un controllo specifico; if (param in qualche stato B) ritorno, un altro controllo specifico; lanciare la nuova NotSupportedException(); } Se qualcuno ha aggiunto un altro possibile stato che potrebbe essere raggiunto quando si chiama questo metodo, lo sviluppatore dovrebbe essere l'aggiunta di un terzo if. Quindi per me raggiungere l'ultima riga del metodo è un'eccezione non supportata. Cosa ne pensi? – Skychan

Problemi correlati