Asserzioni nel codice gestito
Un'asserzione, o istruzione Assert
, verifica una condizione specificata come argomento dell'istruzione Assert
. Se la condizione restituisce true, non viene eseguita alcuna azione. Se restituisce false, l'asserzione ha esito negativo. Se è in esecuzione una build di debug, il programma passa alla modalità di interruzione.
Contenuto dell'argomento
Asserzioni nello spazio dei nomi System.Diagnostics
Metodo Debug.Assert
Effetti secondari di Debug.Assert
Personalizzazione del comportamento del metodo Assert
Impostazione di asserzioni nei file di configurazione
Asserzioni nello spazio dei nomi System.Diagnostics
In Visual Basic e Visual C# è possibile utilizzare il metodo Assert
da Debug o Traceche si trovano nello spazio dei nomi System.Diagnostics. Debug I metodi di classe non sono inclusi in una versione Release del programma, quindi non aumentano le dimensioni o riducono la velocità del codice di rilascio.
C++ non supporta i metodi della Debug classe. È possibile ottenere lo stesso effetto utilizzando la classe Trace con compilazione condizionale, ad esempio #ifdef DEBUG
... #endif
.
Metodo Debug.Assert
Utilizzare il metodo System.Diagnostics.Debug.Assert per verificare le condizioni che devono restituire true se il codice è corretto. Si supponga, ad esempio, di aver scritto una funzione di divisione per interi. In base alle regole matematiche, il divisore non può mai essere zero. A tale scopo, utilizzare un'asserzione:
int IntegerDivide ( int dividend , int divisor )
{
Debug.Assert ( divisor != 0 );
return ( dividend / divisor );
}
Quando si esegue questo codice nel debugger, l'istruzione di asserzione viene valutata, ma nella versione di rilascio il confronto non viene eseguito, pertanto non viene generato alcun sovraccarico aggiuntivo.
Di seguito è riportato un altro esempio. Si supponga che esista una classe che implementa un conto corrente:
float balance = savingsAccount.Balance;
Debug.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );
Prima di ritirare denaro dal conto, si desidera assicurarsi che il saldo del conto sia sufficiente per coprire l'importo che si sta preparando a ritirare. Per controllare il saldo, è possibile scrivere un'asserzione:
float balance = savingsAccount.Balance;
Trace.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );
Le chiamate al metodo System.Diagnostics.Debug.Assert scompaiono quando si crea una versione di rilascio del codice. Ciò significa che nella versione di rilascio la chiamata che controlla il saldo scompare. Per risolvere questo problema, è necessario sostituire System.Diagnostics.Debug.Assert con System.Diagnostics.Trace.Assert, che non scompare nella versione di rilascio:
A differenza dalle chiamate a System.Diagnostics.Trace.Assert, le chiamate a System.Diagnostics.Debug.Assert comportano un sovraccarico nella versione di rilascio.
Effetti secondari di Debug.Assert
Quando si usa System.Diagnostics.Debug.Assert, assicurarsi che qualsiasi codice all'interno Assert
non modifichi i risultati del programma se Assert
viene rimosso. In caso contrario, si potrebbe introdurre accidentalmente un bug che si manifesta solo nella versione di rilascio del programma. Prestare particolare attenzione alle asserzioni contenenti chiamate di funzioni o procedure, come quella del seguente esempio:
Questo utilizzo di System.Diagnostics.Debug.Assert potrebbe sembrare sicuro a una prima analisi, ma si supponga che la funzione meas aggiorni un contatore ogni volta che viene chiamata. Quando si compila la versione release, questa chiamata a meas viene eliminata, quindi il contatore non viene aggiornato. Questo è un esempio di funzione con un effetto collaterale. L'eliminazione di una chiamata a una funzione che produce effetti collaterali potrebbe comportare la generazione di un bug che si manifesta solo nella versione di rilascio. Per evitare questi problemi, non inserire chiamate di funzione in un'istruzione System.Diagnostics.Debug.Assert . Utilizzare invece una variabile temporanea:
Anche quando si utilizza System.Diagnostics.Trace.Assert, evitare di inserire chiamate di funzione all'interno di un'istruzione Assert
. Tali chiamate devono essere sicure, perché System.Diagnostics.Trace.Assert le istruzioni non vengono eliminate in una build di rilascio. Tuttavia, se si evitano tali costrutti come abitudine, è meno probabile che si commette un errore quando si usa System.Diagnostics.Debug.Assert.
Requisiti di traccia e debug
Se si crea il progetto usando le procedure guidate di Visual Studio, il simbolo TRACE viene definito per impostazione predefinita nelle configurazioni Release e Debug. Il simbolo DEBUG viene definito per impostazione predefinita solo nella build di debug.
In caso contrario, affinché i metodi Trace funzionino correttamente, è necessario che all'inizio del file di origine del programma sia presente una delle seguenti:
#Const TRACE = True
in Visual Basic#define TRACE
in Visual C# e C++In alternativa, è necessario che il programma venga compilato con l'opzione TRACE:
/d:TRACE=True
in Visual Basic/d:TRACE
in Visual C# e C++Per utilizzare i metodi Debug in una build di rilascio di C# o Visual Basic, è necessario definire il simbolo DEBUG nella configurazione di rilascio.
C++ non supporta i metodi della Debug classe. È possibile ottenere lo stesso effetto utilizzando la classe Trace con compilazione condizionale, ad esempio
#ifdef DEBUG
...#endif
. È possibile definire questi simboli nella finestra di dialogo Pagine delle proprietà del <progetto>. Per altre informazioni, vedere Modifica delle impostazioni di progetto per una configurazione di debug di Visual Basic o Modifica delle impostazioni di progetto per una configurazione di debug di C++.
Argomenti del metodo Assert
System.Diagnostics.Trace.Assert e System.Diagnostics.Debug.Assert accettano fino a tre argomenti. Il primo argomento obbligatorio è la condizione che si desidera verificare. Se si chiama System.Diagnostics.Trace.Assert(Boolean) o System.Diagnostics.Debug.Assert(Boolean) con un solo argomento, il metodo Assert
verifica la condizione e, se il risultato è false, genera il contenuto dello stack di chiamate nella finestra Output. Nell'esempio riportato di seguito sono illustrati i metodi System.Diagnostics.Trace.Assert(Boolean) e System.Diagnostics.Debug.Assert(Boolean):
Il secondo e il terzo argomento, se presenti, devono essere stringhe. Se si chiama il metodo System.Diagnostics.Trace.Assert o System.Diagnostics.Debug.Assert con due o tre argomenti, il primo argomento è una condizione. Il metodo verifica la condizione e, se il risultato è false, genera la seconda e la terza stringa. Nell'esempio riportato di seguito viene illustrato l'utilizzo di System.Diagnostics.Debug.Assert(Boolean, String) e System.Diagnostics.Trace.Assert(Boolean, String) con due argomenti:
Debug.Assert ( stacksize > 0, "Out of stack space" );
Trace.Assert ( stacksize > 0, "Out of stack space" );
Nell'esempio seguente viene illustrato System.Diagnostics.Debug.Assert(Boolean, String, String) e System.Diagnostics.Trace.Assert(Boolean, String, String) usato con tre argomenti:
Debug.Assert ( stacksize > 100, "Out of stack space" , "Failed in inctemp" );
Trace.Assert ( stacksize > 0, "Out of stack space", "Failed in inctemp" );
Personalizzazione del comportamento del metodo Assert
Se si esegue l'applicazione in modalità interfaccia utente, il Assert
metodo visualizza la finestra di dialogo Asserzione non riuscita quando la condizione ha esito negativo. Le azioni che vengono eseguite quando un'asserzione ha esito negativo sono controllate dalla proprietà Listeners o Listeners.
È possibile personalizzare il comportamento di output aggiungendo un oggetto TraceListener alla raccolta Listeners
, rimuovendo un oggetto TraceListener dalla raccolta Listeners
oppure eseguendo l'override del metodo System.Diagnostics.TraceListener.Fail di un oggetto TraceListener
esistente in modo da ottenere un comportamento diverso.
È ad esempio possibile eseguire l'override del metodo System.Diagnostics.TraceListener.Fail per scrivere in un log eventi anziché visualizzare la finestra di dialogo Asserzione non riuscita.
Per personalizzare l'output in questo modo, il programma deve contenere un listener ed è necessario ereditare da TraceListener, nonché eseguire l'override del relativo metodo System.Diagnostics.TraceListener.Fail.
Per altre informazioni, vedere Listener di traccia.
Impostazione di asserzioni nei file di configurazione
Le asserzioni possono essere impostate sia nel file di configurazione del programma sia nel codice. Per altre informazioni, vedere System.Diagnostics.Trace.Assert o System.Diagnostics.Debug.Assert.