C # - Cosa fa il metodo Assert ()? È ancora utile?


156

Sto eseguendo il debug con punti di interruzione e realizzo la chiamata di assert? Ho pensato che fosse solo per i test unitari. Cosa fa di più del breakpoint? Dal momento che posso interrompere il punto di interruzione, perché dovrei usare Assert?


9
A proposito, se sei interessato ad affermazioni dovresti assolutamente approfondire i contratti di codice .
MasterMastic,

Risposte:


200

In una compilazione di debug, Assertaccetta una condizione booleana come parametro e mostra la finestra di dialogo di errore se la condizione è falsa. Il programma procede senza alcuna interruzione se la condizione è vera.

Se compili in Release, tutto Debug.Assertviene automaticamente escluso.


12
come posso ottenere lo stesso comportamento di Debug.Assert in modalità Release?
Hamish Grubijan,

15
Trace.Assert per modo di sgancio apparentemente arbitri: msdn.microsoft.com/en-us/library/... msdn.microsoft.com/en-us/library/e63efys0.aspx
Tim Abell

8
@HamishGrubijan E perché vorresti Debug.Assertin modalità di rilascio?
Camilo Martin,

25
IMO, omettere le asserzioni dal codice di rilascio è come condurre esercitazioni di scialuppe di salvataggio mentre sono ancorate e quindi lasciare le scialuppe di salvataggio quando si naviga. :)
chrisd,

113
Le asserzioni non sono una scialuppa di salvataggio, sono un sistema di rilevamento dell'iceberg. Dal momento che l'utente non sta guidando la nave, un'affermazione nel codice di rilascio dice semplicemente che sono condannati; non permette loro di evitare l'iceberg.
Stefan,

97

Dal codice completo

8 Programmazione difensiva

8.2 Asserzioni

Un'asserzione è il codice utilizzato durante lo sviluppo, in genere una routine o una macro, che consente a un programma di controllarsi mentre viene eseguito. Quando un'asserzione è vera, significa che tutto funziona come previsto. Quando è falso, significa che ha rilevato un errore imprevisto nel codice. Ad esempio, se il sistema presume che un file di informazioni sul cliente non avrà mai più di 50.000 record, il programma potrebbe contenere un'asserzione che il numero di record è inferiore o uguale a 50.000. Finché il numero di record è inferiore o uguale a 50.000, l'affermazione rimarrà silenziosa. Se incontra più di 50.000 record, tuttavia, "affermerà" fortemente che c'è un errore nel programma.

Le asserzioni sono particolarmente utili in programmi complessi e di grandi dimensioni e in programmi ad alta affidabilità. Consentono ai programmatori di eliminare più rapidamente i presupposti dell'interfaccia non corrispondenti, gli errori che si verificano quando il codice viene modificato e così via.

Un'asserzione di solito prende due argomenti: un'espressione booleana che descrive il presupposto che dovrebbe essere vero e un messaggio da visualizzare se non lo è.

(...)

Normalmente, non si desidera che gli utenti vedano i messaggi di asserzione nel codice di produzione; le affermazioni servono principalmente durante lo sviluppo e la manutenzione. Le asserzioni vengono normalmente compilate nel codice in fase di sviluppo e compilate fuori dal codice per la produzione. Durante lo sviluppo, le asserzioni eliminano ipotesi contraddittorie, condizioni impreviste, valori errati passati alle routine e così via. Durante la produzione, vengono compilati fuori dal codice in modo che le asserzioni non degradino le prestazioni del sistema.


2
Il libro, Writing Solid Code, ha anche una grande discussione sull'uso di assert. Sono un ottimo strumento di debug!
zooropa,

39

Dovresti usarlo per i momenti in cui non vuoi interrompere ogni piccola riga di codice per controllare le variabili, ma vuoi ottenere una sorta di feedback se sono presenti determinate situazioni, ad esempio:

Debug.Assert(someObject != null, "someObject is null! this could totally be a bug!");

Se aggiungo una riga di codice simile alla tua sopra, l'esecuzione del mio programma dà il seguente errore: "errore CS0103: il nome" Debug "non esiste nel contesto attuale". Ho bisogno di una sorta di dichiarazione di utilizzo per farlo funzionare?
Josh Desmond,

4
@JoshDesmondSystem.Diagnostics
Sinjai,

16

Assert ti offre anche un'altra opportunità di ridere delle capacità di progettazione dell'interfaccia utente di Microsoft. Voglio dire: una finestra di dialogo con tre pulsanti Annulla, Riprova, Ignora e una spiegazione su come interpretarli nella barra del titolo!


3
Annulla / Riprova / Ignora è classico! Sono state le asserzioni che hanno usato Windows 3.1 per visualizzarlo continuamente?
Devlord,

Fondamentalmente è perché utilizza un MessageBox, che come dici tu risale a Windows 3.1, e ha solo etichette di pulsanti predefinite. Quindi puoi capire perché è nato l'hack, ma non perché è ancora lì nel 2008!
Joe,

4
@Joe Questo è qualcosa che dovrebbe essere visto solo dagli sviluppatori e non dagli utenti finali, quindi l'aggiornamento è probabilmente un elemento con priorità estremamente bassa. Se dà fastidio è possibile modificare le raccolte Debug.Listeners o Trace.Listeners per sostituire il gestore predefinito con uno che fa tutto ciò che si desidera.
Dan Is Fiddling By Firelight,

5
E ora è il 2019 e la stessa finestra di dialogo / pulsanti sono ancora qui!
Bouke,

10

Assert ti consente di affermare che nel tuo codice si applica una condizione (posta o pre). È un modo per documentare le tue intenzioni e avere il debugger che ti informa con una finestra di dialogo se le tue intenzioni non sono soddisfatte.

A differenza di un punto di interruzione, l'Assert si accompagna al codice e può essere utilizzato per aggiungere ulteriori dettagli sull'intenzione.


10

Assert può aiutarti a fornire un comportamento di messaggistica separato tra test e rilascio. Per esempio,

Debug.Assert(x > 2)

attiverà un'interruzione solo se si esegue una build di "debug", non una build di rilascio. C'è un esempio completo di questo comportamento qui


10

Prima di tutto il Assert()metodo è disponibile per Tracee Debugclassi.
Debug.Assert()viene eseguito solo in modalità debug.
Trace.Assert()è in esecuzione in modalità Debug and Release.

Ecco un esempio:

        int i = 1 + 3;
        // Debug.Assert method in Debug mode fails, since i == 4
        Debug.Assert(i == 3);
        Debug.WriteLine(i == 3, "i is equal to 3");

        // Trace.Assert method in Release mode is not failing.
        Trace.Assert(i == 4);
        Trace.WriteLine(i == 4, "i is equla to 4");

        Console.WriteLine("Press a key to continue...");
        Console.ReadLine();

Esegui questo codice in modalità Debug e quindi in modalità Rilascio.

inserisci qui la descrizione dell'immagine

Noterai che durante la modalità Debug la tua Debug.Assertdichiarazione di codice fallisce, otterrai una finestra di messaggio che mostra la traccia dello stack corrente dell'applicazione. Ciò non accade in modalità Rilascio poiché la Trace.Assert()condizione è vera (i == 4).

WriteLine() Il metodo offre semplicemente un'opzione per registrare le informazioni nell'output di Visual Studio. inserisci qui la descrizione dell'immagine


5

Le asserzioni sono fortemente presenti in Design by Contract (DbC) che, a quanto ho capito, è stato introdotto / approvato da Meyer, Bertand. 1997. Contruction software orientato agli oggetti.

Una caratteristica importante è che non devono produrre effetti collaterali, ad esempio è possibile gestire un'eccezione o intraprendere un'azione diversa con un'istruzione if (programmazione difensiva).

Le asserzioni vengono utilizzate per verificare le condizioni pre / post del contratto, il rapporto cliente / fornitore - il cliente deve assicurarsi che siano soddisfatte le condizioni preliminari del fornitore, ad es. invia £ 5 e il fornitore deve assicurarsi che siano soddisfatte le condizioni postali, ad es. consegna 12 rose. (Solo una semplice spiegazione del cliente / fornitore - può accettare di meno e fornire di più, ma riguardo alle asserzioni). C # introduce anche Trace.Assert (), che può essere utilizzato per il codice di rilascio.

Per rispondere alla domanda sì, sono ancora utili, ma possono aggiungere complessità + leggibilità a codice e tempo + difficilmente da mantenere. Dovremmo ancora usarli? Sì, li useremo tutti? Probabilmente no, o meno nella misura in cui descrive Meyer.

(Anche il corso OU Java su cui ho appreso questa tecnica mostrava solo semplici esempi e il resto del codice non applicava le regole di asserzione DbC sulla maggior parte del codice, ma si presumeva fosse usato per assicurare la correttezza del programma!)


3

Il mio modo di pensare è Debug.Assert è un modo per stabilire un contratto su come si suppone che debba essere chiamato un metodo, concentrandosi su dettagli specifici sui valori di un parametro (anziché solo sul tipo). Ad esempio, se non si prevede di inviare un valore nullo nel secondo parametro, aggiungere l'Assert attorno a quel parametro per dire al consumatore di non farlo.

Impedisce a qualcuno di utilizzare il codice in modo ossuto. Ma consente anche a quel modo spericolato di passare alla produzione e non dare il cattivo messaggio a un cliente (supponendo che tu costruisca una build di rilascio).


6
È importante sottolineare, tuttavia, che i parametri non validi sui metodi pubblici dovrebbero generare eccezioni agli argomenti. Solo i metodi privati ​​dovrebbero convalidare l'input con asserzioni. I valori che arrivano dall'esterno sono sempre sospetti!
Jeffrey L Whitledge,
Utilizzando il nostro sito, riconosci di aver letto e compreso le nostre Informativa sui cookie e Informativa sulla privacy.
Licensed under cc by-sa 3.0 with attribution required.