Controllare il debug del codice grazie al namespace System.Diagnostics

Scritto da  Massimo Bonanni il mercoledì 26 gennaio 2011
Linguaggio: VB   •  Framework: 2.0,3.0,3.5,4.0   •  Livello: 100


In questo breve articolo vorrei mostrarvi come sia possibile controllare il flusso di debug dei nostri applicativi utilizzando alcune classi presenti nel namespace System.Diagnostics.

ConditionalAttribute

L'attributo ConditionaAttribute ci consente di includere (o escludere) metodi dal flusso di esecuzione in base alla presenza o meno di una costante di compilazione.

Ad esempio, supponiamo di avere la seguente applicazione console:

Module Module1

Sub Main()
Console.WriteLine("Console start")
WriteLog()
Console.WriteLine("Console end")
End Sub

<Diagnostics.Conditional("LOG")>
Private Sub WriteLog()
Console.WriteLine("WriteLog")
End Sub

End Module

 

Se non definiamo la costante di compilazione LOG, il codice che viene compilato è il seguente: 

Figura1

 Come si può osservare, il corpo del metodo decorato con l'attributo ConditionalAttribute è stato compilato ma non è stata inserita la chiamata allo stesso che si sarebbe dovuta trovare tra le due istruzioni Console.WriteLine del Main. Questo significa che, quando eseguiamo, ad esempio, il debug della nostra applicazione, vedremo il punto di esecuzione saltare la chiamata al metodo WriteLog().
Definiamo, ora, la costante di compilazione LOG e per fare questo apriamo la finestra delle proprietà dell'applicazione console: 

Figura2

 Se compiliamo dopo aver salvato i cambiamenti alle proprietà otteniamo:

Figura3

 Il metodo, questa volta, viene effettivamente richiamato.
La costante di compilazione è definibile anche, all'interno del modulo, con la direttiva #Const nel seguente modo:

#Const LOG = False

 

L'utilizzo dell'attributo ConditionalAttribute è una valida alternativa ai costrutti #If...#End If anche se non è applicabile a quei metodi che ritornano dei valori (function). In questo caso, per poter applicare l'attributo è necessario convertire la function in una sub e restituire il valore come argomento byref.


DebuggerDisplayAttribute
La classe DebuggerDisplayAttribute ci permette di personalizzare il modo in cui appare il tootltip di debug di un tipo. Supponiamo di avere la classe Employee: 

Public Class Employee
Public Property LastName As String
Public Property FirstName As String
End Class

 

E di voler eseguire il debug di una semplice applicazione console:

Figura4

 Il tooltip che ci permette di vedere i valori assunti dalla variabile employee ci dice che la variabile è di tipo Employee e ci obbliga ad aprire l'albero delle proprietà per vedere il contenuto della stessa.
Per fare in modo che nel tooltip appaia una stringa riempita con i valori contenuti nelle proprietà della variabile (che ci permetterebbe a colpo d'occhio di capire che oggetto abbiamo in debug), possiamo implementare l'override del metodo ToString. Questo fatto ci obbliga, però, ad utilizzare un metodo che è, di solito, utilizzato per scopi applicativi (ad esempio per mostrare i dati in una listbox)  per scopi di debug. Inoltre, non è detto che le informazioni che dobbiamo mostrare in debug siano le stesse da mostrare con il ToString(). Per risolvere questo problema ci viene in aiuto l'attributo DebuggerDisplayAttribute il cui scopo è definire come deve essere visualizzato il nostro oggetto quando viene aperto il tooltip di debug: 

<Diagnostics.DebuggerDisplay("Employee = {LastName} {FirstName}")>
Public Class Employee
Public Property LastName As String
Public Property FirstName As String
End Class

 

 In questo modo otteniamo: 

Figura5

L'attributo può essere applicato ad assembly, classi, strutture, campi, proprietà o delegate.

DebuggerHiddenAttribute

La classe DebuggerHiddenAttribute permette di "nascondere" un costruttore, un metodo o una proprietà. Decorando un membro con questo attributo facciamo si che quando si esegue il debug non si possa eseguire uno step-into all'interno del metodo o fermarsi in un breakpoint interno al metodo stesso.

Un esempio di utilizzo dell'attributo è il seguente:

Public Class Class1

Public Function NotHiddenMethod() As Boolean
Return True
End Function

<Diagnostics.DebuggerHidden()> _
Public Function HiddenMethod() As Boolean
Return True
End Function
End Class

 

Di fatto, il metodo HiddenMethod non può essere debuggato né utilizzando lo step-into né inserendo un breakpoint all'interno (per la cronaca l'ambiente di sviluppo permette di inserire il breakpoint ma questo non è attivo).

DebuggerStepThroughAttribute
DebuggerStepThroughAttribute  funziona in maniera analoga al precedente attributo ma si limita solo a non permettere l'esecuzione dello Step-Into nel metodo e non a disabilitare i breakpoint interni. In più rispetto al precedente attributo, questo può essere applicato anche a livello di classe o struttura in modo da inibire tutti i membri della classe o struttura stessa.
In realtà l'attributo funziona in due differenti modalità in base all'opzione "Enable Just My Code" impostata nelle proprietà di debug del progetto:

Figura6

Se è abilitata l'opzione Just My Code, l'attributo si comporta esattamente come l'attributo precedente non permettendo neanche i breakpoint interni ai membri decorati.
Se non è abilitata l'opzione Just My Code, invece, il flusso di esecuzione in debug si fermerà su eventuali breakpoint interni ai membri pur non permettendo lo step-into.

DebuggerBrowsableAttribute
L'attributo DebuggerBrowsable può essere applicato ad una proprietà o ad un campo e permette di nascondere la proprietà o il campo nella finestra di debug.
Ad esempio, prendiamo la classe: 

Public Class Class1
Public Property VisibleProperty As String

<Diagnostics.DebuggerBrowsable(DebuggerBrowsableState.Never)>
Public Property InvisibleProperty As String
End Class

 

La proprietà InvisibleProperty, pur essendo pubblica, non sarà visualizzata nella finestra di debug:

Figura7

 Il namespace System.Diagnostics contiene, oltre agli attributi che consentono di controllare il flusso del debug delle nostre applicazioni, anche tutta una serie di classi per interagire con l'eventlog, i processi, i performance counters, etc., etc. Maggiori informazioni al seguente link


Tags: Visual Studio 2010,VB.NET

 
x