Direi sicuramente che c'è un difetto nel design se senti la necessità di gettare eccezioni da un setter o getter di proprietà.
Una proprietà è un'astrazione che rappresenta qualcosa che è solo un valore . E dovresti essere in grado di impostare un valore senza temere che ciò possa generare un'eccezione. *
Se l'impostazione della proprietà produce un effetto collaterale, quello dovrebbe invece essere implementato come metodo. E se non produce alcun effetto collaterale, non dovrebbe essere generata alcuna eccezione.
Un esempio già menzionato in una risposta diversa è la Stream.Position
proprietà. Ciò produce effetti collaterali e può generare eccezioni. Ma questo setter proprietà è fondamentalmente solo un wrapper Stream.Seek
che potresti chiamare invece.
Personalmente, credo che la posizione non avrebbe dovuto essere una proprietà scrivibile.
Un altro esempio in cui potresti essere tentato di lanciare un'eccezione da un setter proprietà è nella convalida dei dati:
public class User {
public string Email {
get { return _email; }
set {
if (!IsValidEmail(value)) throw InvalidEmailException(value);
_email = value;
}
}
Ma esiste una soluzione migliore a questo problema. Introdurre un tipo che rappresenti un indirizzo email valido:
public class Email {
public Email(string value) {
if (!IsValidEmail(value)) throw new InvalidEmailException(value);
...
}
...
}
public class User {
public Email Email { get; set; }
}
La Email
classe garantisce che non può contenere un valore che non sia un indirizzo e-mail valido e che le classi che devono archiviare le e-mail sono esonerate dal dovere di convalidarle.
Ciò porta anche a una maggiore coesione (un indicatore di una buona progettazione del software): la conoscenza di ciò che è un indirizzo e-mail e di come viene convalidato esiste solo nella Email
classe, che ha solo quella preoccupazione.
* ObjectDisposedException è l'unica eccezione valida (nessun gioco di parole intenzionale) a cui riesco a pensare al momento.