I MSDN guidelines for standard exceptions stati:
Fare valore d'uso per il nome del parametro valore implicito di immobili in setter.
Il seguente esempio di codice illustra una struttura che genera un'eccezione se il chiamante passa un argomento nullo.
public IPAddress Address
{
get
{
return address;
}
set
{
if(value == null)
{
throw new ArgumentNullException("value");
}
address = value;
}
}
Inoltre, il MSDN guidelines for property design dicono:
evitare di gettare eccezioni getter proprietà.
I getter di proprietà devono essere semplici operazioni senza precondizioni. Se un getter potrebbe generare un'eccezione, considerano ridisegnare la proprietà di essere un metodo. Questa raccomandazione non è non applicabile agli indicizzatori. Gli indicizzatori possono eseguire le eccezioni a causa di argomenti non validi .
E 'valida e accettabile per gettare eccezioni da un setter di proprietà.
Quindi buttare ArgumentNullException
nel setter sul null
, e ArgumentException
sulla stringa vuota, e non fare nulla nel getter. Poiché il setter lancia e solo tu hai accesso al campo di supporto, è facile accertarti che non contenga un valore non valido. Avere il lancio getter è quindi inutile. Questo potrebbe tuttavia essere un buon punto per utilizzare Debug.Assert
.
Se davvero non si può fornire un valore predefinito appropriato, quindi suppongo avete tre opzioni:
ritorno giusto tutto ciò che è nella proprietà e documentare questo comportamento come parte del contratto di utilizzo. Lascia che sia il chiamante a occuparsene. Potresti anche richiedere un valore valido nel costruttore. Questo potrebbe essere completamente inappropriato per la tua applicazione.
Sostituire la proprietà con metodi: un metodo setter che genera quando viene passato un valore non valido e un metodo getter che genera InvalidOperationException
quando alla proprietà non è mai stato assegnato un valore valido.
Throw InvalidOperationException
dal getter, come si potrebbe considerare 'proprietà non è mai stato assegnato' uno stato non valido. Mentre non dovresti normalmente buttare da getter, suppongo che questo potrebbe essere un buon motivo per fare un'eccezione.
Se scegli le opzioni 2 o 3, si dovrebbe includere anche un metodo che restituisce un TryGet- bool
che indica se la proprietà è stata impostata su un valore valido, e in caso affermativo restituisce tale valore in un parametro out
. Altrimenti si costringono i chiamanti a essere pronti a gestire un InvalidOperationException
, a meno che non abbiano precedentemente impostato la proprietà da soli e quindi sappiano che non genererà. Confronta int.Parse
versus int.TryParse
.
Io suggerirei di utilizzare l'opzione 2 con il metodo TryGet. Non viola alcuna linea guida e impone requisiti minimi sul codice chiamante.
Circa gli altri suggerimenti
ApplicationException
è troppo generale. ArgumentException
è un po 'troppo generico per null
, ma va bene altrimenti.MSDN docs again:
gettare la più specifica (la più derivata) eccezione che è appropriata. Ad esempio, se un metodo riceve un argomento null (Nothing in Visual Basic), dovrebbe generare System.ArgumentNullException invece del suo tipo di base System.ArgumentException.
In realtà non si dovrebbe usare ApplicationException
a tutti (docs):
Do derivano eccezioni personalizzate dalla T: classe System.Exception piuttosto che il T: class System.ApplicationException.
Inizialmente si pensava che le eccezioni personalizzate dovessero derivare dalla classe ApplicationException; tuttavia, questo non è stato trovato per aggiungere un valore significativo. Per ulteriori informazioni, vedere Best practice per la gestione delle eccezioni.
InvalidOperationException
è destinato non per quando gli argomenti di un metodo o una proprietà non sono validi, ma per quando il operazione nel suo complesso è valido (docs). Non deve essere gettato dal setter:
fare un'eccezione System.InvalidOperationException se in uno stato inadeguato. System.InvalidOperationException deve essere generato se un insieme di proprietà o una chiamata al metodo non sono appropriati dato lo stato corrente dell'oggetto. Ad esempio, la scrittura su un System.IO.FileStream che è stato aperto per la lettura dovrebbe generare un'eccezione System.InvalidOperationException.
Incidentalmente, InvalidOperationException
è per quando l'operazione non è valida per stato corrente dell'oggetto. Se l'operazione è sempre non valida per l'intera classe, è necessario utilizzare NotSupportedException
.
Ricordate anche le proprietà sono metodi sintattici zuccherati. – Dykam
Una discussione interessante correlata: http://stackoverflow.com/questions/1488472/best-practices-throwing-exceptions-from-properties – Joren