Creazione e generazione di eccezioni (Guida per programmatori C#)

Le eccezioni vengono utilizzate per indicare che si è verificato un errore durante l'esecuzione di un programma. Gli oggetti eccezione che descrivono un errore vengono creati e quindi generati con la parola chiave throw. Il runtime ricerca quindi il gestore eccezioni maggiormente compatibile.

I programmatori devono generare eccezioni se almeno una delle condizioni seguenti è vera:

  • Il metodo non è in grado di completare la funzionalità definita.

    Se ad esempio un parametro di un metodo contiene un valore non valido:

    static void CopyObject(SampleClass original)
    {
        if (original == null)
        {
            throw new System.ArgumentException("Parameter cannot be null", "original");
        }
    
    }
    
  • Viene effettuata una chiamata non appropriata a un oggetto, in base allo stato di un oggetto.

    Un esempio potrebbe essere la scrittura in un file di sola lettura. Nei casi in cui lo stato di un oggetto non consente un'operazione, generare un'istanza di InvalidOperationException o un oggetto basato su una derivazione di questa classe. Di seguito viene riportato un esempio di un metodo che genera un oggetto InvalidOperationException:

    class ProgramLog
    {
        System.IO.FileStream logFile = null;
        void OpenLog(System.IO.FileInfo fileName, System.IO.FileMode mode) {}
    
        void WriteLog()
        {
            if (!this.logFile.CanWrite)
            {
                throw new System.InvalidOperationException("Logfile cannot be read-only");
            }
            // Else write data to the log and return.
        }
    }
    
  • Quando un argomento di un metodo genera un'eccezione.

    In questo caso è necessario intercettare l'eccezione originale e creare un'istanza di ArgumentException. L'eccezione originale deve essere passata al costruttore dell'oggetto ArgumentException come il parametro InnerException:

    static int GetValueFromArray(int[] array, int index)
    {
        try
        {
            return array[index];
        }
        catch (System.IndexOutOfRangeException ex)
        {
            System.ArgumentException argEx = new System.ArgumentException("Index is out of range", "index", ex);
            throw argEx;
        }
    }
    

Le eccezioni contengono una proprietà denominata StackTrace. Questa stringa contiene il nome dei metodi sullo stack di chiamate correnti, oltre al nome del file e al numero di riga in cui è stata generata l'eccezione per ciascun metodo. Un oggetto StackTrace viene creato automaticamente da Common Language Runtime (CLR) a partire dal punto dell'istruzione throw, quindi le eccezioni devono essere generate a partire dal punto in cui deve iniziare la traccia dello stack.

Tutte le eccezioni contengono una proprietà denominata Message. Questa stringa deve essere impostata in modo da descrivere il motivo dell'eccezione. Si noti che nel testo del messaggio non devono essere inserite informazioni riservate. Oltre a Message, ArgumentException contiene una proprietà denominata ParamName che deve essere impostata sul nome dell'argomento che ha causato la generazione dell'eccezione. Nel caso di un metodo per l'impostazione di proprietà, ParamName deve essere impostata su value.

I membri di metodi pubblici e protetti devono generare eccezioni ogni volta che non sono in grado di completare le funzioni previste. La classe di eccezioni generata deve corrispondere all'eccezione più specifica disponibile che sia adatta alle condizioni di errore. Queste eccezioni devono essere documentate come parte della funzionalità della classe e le classi derivate o gli aggiornamenti della classe originale devono conservare lo stesso comportamento per la compatibilità con le versioni precedenti. Per ulteriori informazioni, vedere Linee guida di progettazione delle eccezioni.

Azioni da evitare quando vengono generate le eccezioni

Nell'elenco seguente vengono riportate le procedure da evitare quando vengono generate le eccezioni:

  • Le eccezioni non devono essere utilizzate per modificare il flusso di un programma come parte della normale esecuzione. Le eccezioni devono essere utilizzate solo per segnalare e gestire le condizioni di errore.

  • Le eccezioni non devono essere restituite come valore o parametro restituito anziché essere generate.

  • Non generare intenzionalmente System.Exception, System.SystemException, System.NullReferenceException o System.IndexOutOfRangeException dal codice sorgente personalizzato.

  • Non creare eccezioni che possono essere generate in modalità di debug ma non in modalità di rilascio. Per identificare gli errori di runtime durante la fase di sviluppo, utilizzare invece il metodo Debug Assert.

Definizione delle classi di eccezioni

I programmi possono generare una classe di eccezioni predefinite disponibile nello spazio dei nomi System (tranne nei casi indicati in precedenza) oppure creare classi di eccezioni specifiche derivandole da Exception. Le classi derivate devono definire almeno quattro costruttori: uno predefinito, uno che imposta la proprietà Message e uno che imposta sia la proprietà Message che la proprietà InnerException. Il quarto costruttore viene utilizzato per serializzare l'eccezione. Le nuove classi di eccezioni devono essere serializzabili. Di seguito è riportato un esempio.

[Serializable()]
public class InvalidDepartmentException : System.Exception
{
    public InvalidDepartmentException() : base() { }
    public InvalidDepartmentException(string message) : base(message) { }
    public InvalidDepartmentException(string message, System.Exception inner) : base(message, inner) { }

    // A constructor is needed for serialization when an
    // exception propagates from a remoting server to the client. 
    protected InvalidDepartmentException(System.Runtime.Serialization.SerializationInfo info,
        System.Runtime.Serialization.StreamingContext context) { }
}

Le nuove proprietà devono essere aggiunte alla classe di eccezioni solo quando i dati che forniscono sono utili per risolvere l'eccezione. Se le nuove proprietà vengono aggiunte alla classe di eccezioni derivata, è necessario eseguire l'override di ToString() in modo che restituisca le informazioni aggiunte.

Specifiche del linguaggio C#

Per ulteriori informazioni, vedere la Specifiche del linguaggio C#. La specifica del linguaggio è la fonte ufficiale per la sintassi e l'utilizzo di C#.

Vedere anche

Riferimenti

Eccezioni e gestione delle eccezioni (Guida per programmatori C#)

Gestione delle eccezioni (Guida per programmatori C#)

Concetti

Guida per programmatori C#

Gerarchia delle eccezioni