LA STRUTTURA TRY-CATCH E LA GESTIONE DELLE ECCEZIONI

Negli articoli precedenti abbiamo parlato del problema di overflow o di underflow dei tipi di variabili che rappresentano interi o floating point. Quando si verificano questi errori si commette una exception cioè un errore che impedisce il corretto avanzamento del programma creato. A volte non ci si rende conto che si stanno per commettere questo tipo di errori, altre volte invece si è consapevoli che l’istruzione inserita nel codice potrebbe restituire una exception. In questo secondo caso il programmatore può “intercettare” l’eccezione e gestirla come meglio crede, ad esempio con la stampa di un messaggio, o sopprimendola ecc. ecc. Per fare ciò si utilizza la struttura TRY-CATCH. Tale struttura è formata da 2+1 parti: Nella prima parte, che chiameremo TRY, il programmatore inserisce le istruzioni che potrebbero creare errore, nella seconda (CATCH) il programmatore invece inserisce l’istruzione che si deve eseguire se viene registrata un’eccezione. Di default questa istruzione verrà eseguita qualunque sia l’eccezione generata (noi abbiamo parlato delle principali, come l’overflow, ma ne esistono molte altre), oppure decidere di eseguire istruzioni diverse per le diverse eccezioni che possono essere generate. Infine può essere inserita una terza parte, il FINALLY; in questa sezione il programmatore può inserire delle istruzione che verranno eseguite a prescindere, cioè sia nel caso in cui si commettesse un’eccezione, sia nel caso in cui ciò non accada. Vediamo un rapido esempio

Public Function Fattoriale (n As Integer) As Integer
 Dim Fatt As Integer = 2
 Try
  For i = 3 To n
   Fatt *= i
  Next
 Catch ex As OverflowException
  Return -1
 End Try
 Return Fatt
End Function

Il codice appena scritto potrebbe essere utilizzato per il calcolo del fattoriale nel linguaggio VB.NET. In questo caso il try-catch viene utilizzato per intercettare un errore di overflow, infatti i numeri fattoriali tendono a crescere molto all’aumentare del valore n, perciò non è difficile credere che si possa incorrere in questo tipo di errore; basti pensare che con una rappresentazione a 32bit come Integer, è possibile rappresentare massimo n = 12, mentre con una rappresentazione a 64bit come Long si può arrivare a n = 20. Vediamo ora l’istruzione di chiamata di questa funzione

For j = 3 To 100
 Dim Fatt As Integer = Me.Fattoriale(j)
 Me.RichTextBox1.AppendText(Environment.NewLine & Fatt)
Next

Anche la chiamata della funzione perciò è all’interno di un ciclo. Per questo motivo, a questo punto, ci si potrebbe chiedere se non si è commesso un errore quando si è deciso di inserire la struttura try-catch nella funzione e non nella chiamata. Per rispondere a questa domanda però analizziamo prima meglio cosa succede quando si commette un exception. A questo scopo introduciamo la call stack, cioè la pila di chiamate. Se nel comando in cui si è generata una exception non è presente un try-catch, l’eccezione “risale” la call stack tornando alla chiamata precedente. Se neanche qui trova un try-catch, risale alla chiamata precedente e così via, fino ad arrivare al main. Risulta perciò ovvio ora che la struttura try-catch deve essere inserita solo se è necessaria al programma; se non è necessaria, si inserisce al livello superiore. Nel nostro esempio perciò ha più senso spostare la struttura nella chiamata della funzione, perché è lì che si crea l’eccezione, non nella funzione. Inoltre una regola generale è di non trasformare mai una exception in un valore.

Vediamo ora come gestiscono le eccezioni i due linguaggi VB.NET e C#. La differenza di gestione tra i due è la presenza di default di un Main() o meno. Infatti se si utilizzasse il linguaggio C#, l’exception risalirebbe tutto il codice fino ad arrivare al Main. Perciò ha senso inserire qui un try-catch che possa gestire in modo efficiente le eccezioni, mentre nelle chiamate successive al programma si potrebbero inserire dei try-catch che semplicemente rimandano (throw) l’eccezione al codice chiamante fino a risalire appunto al Main. In VB.NET invece non è presente il Main(), c’è il newForm1 che viene definito come punto d’entrata quando è generato. Per questo motivo VB.NET ammette l’esistenza di un “gestore di eccezione non gestita” che può essere paragonato ad un tory-catch nel Main di C#. Con un menù a tendina posso inserire l’azione da eseguire quando l’errore non è mai rilevato, andando anche a discriminare il tipo di errore.

Lascia un commento

Progetta un sito come questo con WordPress.com
Comincia ora