adszone.org
venerdì 20 settembre 2024
"Il modo corretto di pensare il software"
home
consulenza  vb.net  contatti 
  Visual Basic .NET
  Eccezioni
Domande

Le Eccezioni

Un'eccezione altro non e' che un modo differente per indicare un errore durante l'esecuzione di un programma. A differenza del'usuale gestione degli errori, pero', le eccezioni prevedono dei costrutti piuttosto strutturati, dentro quali individuare un tipo di errore ed intrappolarvelo. Con intrappolare intendo: fare in modo che al verificarsi dell'errore, l'esecuzione del programma venga trasferita proprio nel punto desiderato. Un eccezione s'intrappola con un blocco Try...End Try, piu' esattamente nel blocco Catch definito al suo interno. Se non e' intrappolata, un'eccezione, viene comunque gestita dal sistema con un messaggio che, ahime', causera' anche il termine dell'applicazione. Se invece la intrappoliamo, possiamo gestire l'errore e proseguire con il programma, a patto che cio' sia lecito, cioe' che l'errore non sia fatale.

In .Net un'errore e' impacchettato in un'eccezione che e' un vero e proprio oggetto, contenente informazioni relative alle cause che l'hanno prodotto. La classe Exception e' una classe base che rappresenta un'eccezione generica. Da essa derivano tutte le eccezioni specializzate per i vari tipi di errore che possono presentarsi. FileNotFoundException, ad esempio, e' un eccezione che si presenta quando si tenta di accedere ad un file che non esiste. Essa deriva direttamente da IOException che e' la classe generica per tutti i tipi di eccezione di input/output. Ecco l'albero di derivazione per questo tipo di eccezioni:

System.Object
    System.Exception
        System.SystemException
            System.IO.IOException
                System.IO.DirectoryNotFoundException
                System.IO.EndOfStreamException
                System.IO.FileLoadException
                System.IO.FileNotFoundException
                System.IO.PathTooLongException

Quando si verifica un errore, ci ritroviamo un oggetto di tipo Exception che possiamo interrogare, tramite le sue proprieta', per esaminare cosa lo ha causato. Ecco alcune proprieta' utili:

  • Message - Restituisce il messaggio che descrive l'errore.
  • Source - Il nome del programma o dell'oggetto che ha causato l'errore.
  • StackTrace - Visualizza lo Stack al momento in cui si e' verificato l'errore.
  • TargetSite - Indica il metodo che ha generato l'errore.

1) Al momento dell'errore si dice che viene lanciata un'eccezione. Noi possiamo raccoglierla, esaminarla e prendere provvedimenti. L'esempio1 ci illustrera' le cose:

    Sub Esempio1()

        Dim a As Decimal = 11
        Dim b As Decimal = 0
        Dim r As Decimal
        Dim errori As Integer = 0

        Try

            r = a / b
            System.Console.WriteLine("Il risultato e' " & r)

        Catch e As DivideByZeroException

            System.Console.WriteLine("errore")
            errori += 1
        Finally
            System.Console.Write("Operazione eseguita con " & errori & _
				" errori")
        End Try

        System.Console.ReadLine()
    End Sub

In rosso, abbiamo marcato i vari blocchi che costituiscono la struttura con la quale gestiamo un'eccezione. Questa e' la forma completa, avremmo potuto omettere Finally.

Il blocco Try racchiude le righe di codice per le quali noi vogliamo intrappolare eventuali eccezioni.

Il blocco Catch e' quello che intrappola l'eccezione il cui tipo sia quello specificato come parametro dopo l'As . Da qualsiasi punto del blocco Try, che generi un'eccezione del tipo corrispondente, il flusso del programma passa a questa Catch.

Il blocco Finally e' quella parte di codice che viene comunque eseguita, sia che si presenti un errore, sia che tutto vada bene. Potremmo usarla, ad esempio, per chiudere un file, sia che un operazione di scrittura sia andata in porto, sia che abbia fallito, magari per spazio insufficiente su disco.

Nell'esempio, poiche' tentiamo di dividere a per b e quest'ultima vale zero, si verifichera' un'eccezione. In particolare l'eccezione DivideByZeroException.

2) Il prossimo esempio ci mostra come lanciare un'eccezione. A tale scopo, utilizza l'istruzione Throw alla quale passiamo un oggetto eccezione generico che etichettiamo con un messaggio custom. Notate che avremmo potuto anche derivare una nostra classe personalizzata e lanciarla al posto di Exception. La funzione Verifica rappresenta un modo fantasioso per realizzare il confronto di un numero con altro numero stabilito. Se i numeri non sono uguali viene lanciata un'eccezione, altrimenti non succede niente. Se, pero', si verifica l'eccezione, il blocco catch verra' eseguito e stampera' il messaggio d'errore. Altrimenti l'esecuzione proseguira' normalmente e il messaggio "Ok" sara' stampato. Soltanto se non occorre l'eccezione, la variabile booleana, indovinato, verra' posta a true e quindi causera' l'uscita dal ciclo ed il termine del programma.

    Sub Verifica(ByVal x As Integer)
        If x <> 5 Then Throw New Exception("Riprova") 
    End Sub

    Sub Esempio2()
        Dim indovinato As Boolean = False
        Do
            System.Console.Write("Indovina il numero: ")
            Dim x As String = System.Console.ReadLine()
            Try
                Verifica(x)
                indovinato = True
                System.Console.WriteLine("Ok")
            Catch e As Exception
                System.Console.WriteLine(e.Message)
                indovinato = False
            End Try
        Loop Until indovinato
        System.Console.ReadLine()
    End Sub

3) L'ultimo esempio ci mostra la possibilita' di usare blocchi Catch multipli. Essi sono selettivi in base al tipo di eccezione che si genera nel Try. Ognuno intercetta l'eccezione che gli compete. Si formano, cosi', percosi multipli. La funzione attende l'input dell'utente. Due tipi di errore possono verificarsi. Se l'utente digita un numero fuori dal range 0..255, si ha una OverflowException, perche' la variabile v e' di tipo Byte. Se inserisce 0, otteniamo una DivideByZeroException, e l'errore verra' gestito, in mancanza di una catch specifica, dalla catch per un eccezione generica. Questo meccanismo e' possibile perche' tutte le eccezioni derivano da quella generica.

    Sub Esempio3()
        Dim v As Byte
        Dim d1 As Decimal = 1
        Try
            v = System.Console.ReadLine()
            d1 = d1 / v
        Catch eo As OverflowException 
            System.Console.WriteLine("Overflow")
        Catch e As Exception 
            System.Console.WriteLine(e.Message)
        End Try
        System.Console.WriteLine("premi invio")
        System.Console.ReadLine()
    End Sub
Ultimo aggiornamento 13/01/2004