Comprendo che un'eccezione nel programma significa che è accaduto qualcosa di imprevedibile (ma non così grave da bloccare inevitabilmente l'applicazione!). La sequenza try-catch-finally mi rende triste perché il programma è più difficile da leggere (un livello in più di parentesi graffe) e più difficile da capire (salta da qualsiasi posizione in caso di eccezione, GOTO è deprecato).
Dato che abbiamo OOP, suggerisco di creare una classe proxy che, in caso di eccezione, la consumi in modo silenzioso, restituisce un valore predefinito e attiva un evento onError. Quindi, se propagiamo un'eccezione, abbiamo invece una chiamata onError e i due svantaggi sopra menzionati sono risolti. Guarda l'esempio in C #:
Atteggiamento delle eccezioni standard
class Computer {
// let's say we need to propagate exception and decide what to do lately
public int divide(int a, int b) {
int result = a / b;
return result;
}
}
class Program {
public static void Main() {
Computer c = new Computer();
try {
Console.WriteLine(c.divide(1, 0));
}
catch(ArithmeticException e) {
// we are teleported here from the middle of Computer.divide method!
// do something
}
}
} // three levels of brackets (without namespace) in such trivial example??
Atteggiamento del gestore onError
class ProxyComputer {
private Computer c = new Computer();
// it is not virtual, can not be overriden
public int divide(int a, int b) {
// alas, exceptions are standard, but we can stop them in this class
try {
return c.divide(a, b);
}
catch(ArithmeticException e) {
this.onError(e);
}
}
protected virtual void onError(Exception e) {
// do nothing
}
}
class MoreStrictComputer : ProxyComputer {
protected override void onError(Exception e) {
// mail to IT department, revert all transactions etc.
Console.WriteLine("I can't seem to do that");
}
}
class Program {
public static void Main() {
ProxyComputer pc = new ProxyComputer();
MoreStrictComputer msc = new MoreStrictComputer();
// fires onError instead of exception
Console.WriteLine(pc.divide(1, 0)); // no problem
Console.WriteLine(msc.divide(1, 0)); // this time it won't be so easy
}
} // only two levels of brackets
Spesso vedo blocchi di cattura vuoti (o banali). Ciò significa che i programmatori spesso considerano le eccezioni come nessuna situazione problematica, ma con un'attitudine standard alle eccezioni, devono comunque preoccuparsi di provare a catturare. Il secondo atteggiamento lo rende opzionale.
Quindi la domanda è: quale soluzione preferiresti? È una specie di schema o mi manchi qualcosa?
Modifica come suggerisce Paul Equis, throw e;
deve essere predefinito sul comportamento dell'Error, non sul silenzio del do-nothing swalowing.