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 l'esecuzione avviene all'interno di una build di debug, viene attivata la modalità di interruzione.
In questo argomento
Asserzioni nello spazio dei nomi System.Diagnostics
Metodo Debug.Assert
Effetti secondari di Debug.Assert
Requisiti di traccia e debug
Argomenti del metodo 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. I metodi della classe Debug non sono inclusi in una versione di rilascio del programma, pertanto non aumentano le dimensioni né riducono la velocità del codice di rilascio.
C++ non supporta i metodi della classe Debug. È possibile ottenere lo stesso effetto utilizzando la classe Trace con compilazione condizionale, ad esempio #ifdef DEBUG... #endif.
In questo argomento
Metodo Debug.Assert
Utilizzare il metodo 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:
Function IntegerDivide(ByVal dividend As Integer, ByVal divisor As Integer) As Integer
Debug.Assert(divisor <> 0)
Return CInt(dividend / divisor)
End Function
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:
Dim amount, balance As Double
balance = savingsAccount.balance
Debug.Assert(amount <= balance)
SavingsAccount.Withdraw(amount)
float balance = savingsAccount.Balance;
Debug.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );
Prima di prelevare denaro dal conto, si desidera verificare che il saldo sia sufficiente a coprire la somma di denaro che si intende ritirare. Per controllare il saldo, è possibile scrivere un'asserzione:
Dim amount, balance As Double
balance = savingsAccount.balance
Trace.Assert(amount <= balance)
SavingsAccount.Withdraw(amount)
float balance = savingsAccount.Balance;
Trace.Assert ( amount <= balance );
savingsAccount.Withdraw ( amount );
Le chiamate al metodo 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, sostituire Debug.Assert con Trace.Assert, che non scompare nella versione di rilascio:
A differenza dalle chiamate a Debug.Assert, le chiamate a Trace.Assert comportano un sovraccarico nella versione di rilascio.
In questo argomento
Effetti secondari di Debug.Assert
Quando si utilizza Debug.Assert, assicurarsi che il codice contenuto in 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:
' unsafe code
Debug.Assert (meas(i) <> 0 )
// unsafe code
Debug.Assert (meas(i) != 0 );
Questo utilizzo di 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 di rilascio, la chiamata a meas viene eliminata, pertanto 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 questo tipo di problema, non inserire chiamate di funzione in un'istruzione Debug.Assert, Utilizzare invece una variabile temporanea:
temp = meas( i )
Debug.Assert (temp <> 0)
temp = meas( i );
Debug.Assert ( temp != 0 );
Anche quando si utilizza Trace.Assert, evitare di inserire chiamate di funzione all'interno di un'istruzione Assert. Queste chiamate non dovrebbero presentare rischi in quanto le istruzioni Trace.Assert non vengono eliminate nella build di rilascio. Se tuttavia si cerca di evitare sempre tali costrutti, è meno probabile che si commetta un errore quando si utilizza Debug.Assert.
In questo argomento
Requisiti di traccia e debug
Se si crea un progetto utilizzando le procedure guidate di Visual Studio, per impostazione predefinita il simbolo TRACE viene definito in entrambe le configurazioni di rilascio e di 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 classe Debug. È 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à di <Progetto>. Per ulteriori 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
Trace.Assert e Debug.Assert accettano fino a tre argomenti. Il primo argomento obbligatorio è la condizione che si desidera verificare. Se si chiama Trace.Assert(Boolean) o 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 Trace.Assert(Boolean) e Debug.Assert(Boolean):
Debug.Assert(stacksize > 0)
Trace.Assert(stacksize > 0)
Debug.Assert ( stacksize > 0 );
Trace.Assert ( stacksize > 0 );
Il secondo e il terzo argomento, se presenti, devono essere stringhe. Se si chiama il metodo Trace.Assert o 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 Debug.Assert(Boolean, String) e Trace.Assert(Boolean, String) con due argomenti:
Debug.Assert(stacksize > 0, "Out of stack space")
Trace.Assert(stacksize > 0, "Out of stack space")
Debug.Assert ( stacksize > 0, "Out of stack space" );
Trace.Assert ( stacksize > 0, "Out of stack space" );
Nell'esempio riportato di seguito sono illustrati i metodi Assert e Assert:
Debug.Assert(stacksize > 0, "Out of stack space. Bytes left:" , Format(size, "G"))
Trace.Assert(stacksize > 0, "Out of stack space. Bytes left:" , Format(size, "G"))
Trace.Assert(stacksize > 0, "Out of stack space. Bytes left:", "inctemp failed on third call" )
Debug.Assert ( stacksize > 100, "Out of stack space" , "Failed in inctemp" );
Trace.Assert ( stacksize > 0, "Out of stack space", "Failed in inctemp" );
In questo argomento
Personalizzazione del comportamento del metodo Assert
Se l'applicazione viene eseguita nella modalità interfaccia utente, il metodo Assert 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 TraceListener.Fail di un oggetto TraceListener esistente in modo da ottenere un comportamento diverso.
È ad esempio possibile eseguire l'override del metodo 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 TraceListener.Fail.
Per ulteriori informazioni, vedere Listener di traccia.
In questo argomento
Impostazione di asserzioni nei file di configurazione
Le asserzioni possono essere impostate sia nel file di configurazione del programma sia nel codice. Per ulteriori informazioni, vedere Trace.Assert o Debug.Assert.
Vedere anche
Attività
Procedura: compilare in modo condizionale con traccia e debug
Riferimenti
Concetti
Altre risorse
Traccia e strumentazione di applicazioni
Preparazione al debug: tipi di progetto C#, F# e Visual Basic