Condividi tramite


Generazione di eccezioni

Le eccezioni vengono generate quando un membro non riesce a eseguire correttamente l'operazione per cui è stato progettato. In questo caso, si verifica un errore di esecuzione. Se ad esempio il metodo Connect non riesce a connettersi all'endpoint remoto specificato, si verificherà un errore di esecuzione e verrà generata un'eccezione.

Le seguenti linee guida contribuiscono a garantire che vengano generate eccezioni al momento opportuno.

Non restituire codici di errore. Le eccezioni costituiscono la tecnica principale di segnalazione degli errori nei framework.

In Linee guida di progettazione delle eccezioni vengono descritti molti dei vantaggi che è possibile ottenere dall'utilizzo delle eccezioni.

Segnalare gli errori di esecuzione mediante la generazione di eccezioni. Se un membro non riesce a eseguire correttamente l'operazione per cui è stato progettato, questa situazione dovrà essere considerata un errore di esecuzione e sarà opportuno generare un'eccezione.

Valutare l'opportunità di terminare il processo mediante una chiamata a System.Environment.FailFast(System.String) (una funzionalità di .NET Framework versione 2.0), anziché la generazione di un'eccezione, se nel codice viene riscontrata una situazione in cui non è sicuro proseguire l'esecuzione.

Non utilizzare le eccezioni per il normale flusso di controllo, se possibile. Tranne per gli errori di sistema e per le operazioni con potenziali race condition, nell'ambito di un framework dovrebbero essere progettate API che consentano agli utenti di scrivere codice che non determina la generazione di eccezioni. Può ad esempio essere opportuno fornire un sistema per la verifica delle condizioni preliminari prima della chiamata a un membro per consentire la scrittura di codice in cui non vengono generate eccezioni.

Nell'esempio di codice riportato di seguito viene illustrato come eseguire il testing per impedire la generazione di eccezioni quando una stringa di messaggio è null (Nothing in Visual Basic).

Public Class Doer

    ' Method that can potential throw exceptions often.
    Public Shared Sub ProcessMessage(ByVal message As String)
        If (message = Nothing) Then
            Throw New ArgumentNullException("message")
        End If
    End Sub

    ' Other methods...
End Class

Public Class Tester

    Public Shared Sub TesterDoer(ByVal messages As ICollection(Of String))
        For Each message As String In messages
            ' Test to ensure that the call 
            ' won't cause the exception.
            If (Not (message) Is Nothing) Then
                Doer.ProcessMessage(message)
            End If
        Next
    End Sub
End Class
public class Doer
{
    // Method that can potential throw exceptions often.
    public static void ProcessMessage(string message)
    {
        if (message == null)
        {
            throw new ArgumentNullException("message");
        }
    }
    // Other methods...
}

public class Tester
{
    public static void TesterDoer(ICollection<string> messages)
    {
        foreach (string message in messages)
        {
            // Test to ensure that the call
            // won't cause the exception.
            if (message != null)
            {
                Doer.ProcessMessage(message);
            }
        }
    }
}
public ref class Doer
{
public:
    // Method that can potential throw exceptions often.
    static void ProcessMessage(String^ message)
    {
        if (message == nullptr)
        {
            throw gcnew ArgumentNullException("message");
       }
    }
    // Other methods...
};

public ref class Tester
{
public:
    static void TesterDoer(ICollection<String^>^ messages)
    {
        for each (String^ message in messages)
        {
            // Test to ensure that the call
            // won't cause the exception.
            if (message != nullptr)
            {
                Doer::ProcessMessage(message);
            }
        }
    }
};

Per ulteriori informazioni sui modelli di progettazione che possono ridurre il numero di eccezioni generate, vedere Eccezioni e prestazioni.

Valutare l'impatto che può avere la generazione di eccezioni a livello di prestazioni.

Documentare tutte le eccezioni generate da membri chiamabili pubblicamente a causa di una violazione del contratto del membro, anziché un errore di sistema, e gestirle come parte del contratto. Le eccezioni che sono parte del contratto non devono cambiare da una versione a quella successiva.

Non definire membri pubblici che possono generare o meno le eccezioni in base a una determinata opzione.

Ad esempio, non definire membri come quello riportato di seguito:

Private Function ParseUri(ByVal uriValue As String, ByVal throwOnError As Boolean) As Uri
Uri ParseUri(string uriValue, bool throwOnError)
Uri^ ParseUri(String^ uriValue, bool throwOnError)

Non definire membri pubblici che restituiscono eccezioni come valore restituito o come parametro out.

Questa linea guida è applicabile ai membri visibili pubblicamente. È comunque accettabile utilizzare un metodo di supporto privato per costruire e inizializzare eccezioni.

Valutare l'opportunità di utilizzare metodi per la creazione di eccezioni. Accade di frequente che venga generata la stessa eccezione da diverse posizioni. Per evitare codice di dimensioni eccessive, utilizzare metodi di supporto per la creazione di eccezioni e l'inizializzazione delle relative proprietà.

Il metodo di supporto non deve generare l'eccezione, altrimenti la traccia dello stack non rifletterà con precisione lo stack di chiamate da cui l'eccezione è stata causata.

Non generare eccezioni da blocchi di filtri eccezioni. Quando un filtro eccezioni genera un'eccezione, questa viene rilevata da Common Language Runtime (CLR) e il filtro restituisce false. Non è possibile distinguere questo comportamento dai casi in cui viene eseguito il filtro e viene restituito false in modo esplicito. Risulta quindi molto difficile eseguirne il debug.

In alcuni linguaggi, ad esempio C#, i filtri eccezioni non sono supportati.

Evitare di generare eccezioni esplicitamente dai blocchi finally. Sono comunque accettabili le eccezioni generate implicitamente, risultanti da chiamate a metodi.

Portions Copyright 2005 Microsoft Corporation. Tutti i diritti riservati.

Portions Copyright Addison-Wesley Corporation. Tutti i diritti riservati.

Per ulteriori informazioni sulle linee guida di progettazione, vedere “le linee guida di progettazione di Framework: Idiomi convenzioni, e modelli per libro raccolte riutilizzabili .NET„ di Krzysztof Cwalina e brad Abrams, emessi da Addison-Wesley, 2005.

Vedere anche

Concetti

Scelta del tipo corretto di eccezione da generare

Altre risorse

Linee guida di progettazione per lo sviluppo di librerie di classi

Linee guida di progettazione delle eccezioni