Una parte dell'esame 70-536 considera alcune delle classi attributo che vengono usate per decorare assembly, classi, metodi, proprietà delle nostre classi. Alcune sono davvero comode ed utili, e secondo me possono davvero velocizzare il debugging delle nostre classi, soprattutto una volta che diamo per assodate certe funzionalità e non vogliamo più, per esempio, entrare nel codice C# che sappiamo funzionare bene. Alcuni degli attributi che elencherò qui di seguito regolano il funzionamento dello Step-Into e dello Step-Over durante l'esecuzione del codice passo-passo. E' un concetto semplice, ma ci tengo a chiarirlo attraverso l'uso di un semplice screenshot direttamente dal mio VS2005.
L'immagine qui sopra prende parte del codice del mio Main(). Ho impostato un breakpoint sulla creazione di un nuovo oggetto Shelf chiamato mensola. Se eseguissi il codice, l'esecuzione si bloccherebbe nel punto indicato. A questo punto, potrei continuare almeno in due modi diversi:
- Premendo F11 (Step-Into). L'esecuzione entra nel codice del costruttore e ci permette di debuggarlo. Ovviamente, questo vale per metodi, proprietà, etc. etc.
- Premendo F10 (Step-Over). L'esecuzione del codice non entra nel costruttore e la riga evidenziata viene eseguita in un blocco solo.
- Ci sono altri metodi, ad esempio il semplice F5, che continua l'esecuzione normalmente
Detto questo, vediamo uno alla volta le classi attributo più comode per modificare questo comportamento di default.
La classe DebuggerStepThroughAttribute
La classe DebuggerStepThrough permette di decorare un membro della classe imponendo al debugger di eseguire il codice senza effettuare lo Step-Into, anche se noi che stiamo guardando il codice premiamo F11. Per essere più chiari: se decorassimo il costruttore della classe Shelf con questo attributo, anche se premessimo F11 in corrispondenza del breakpoint qui sopra, il debugger non entra ed istanzia la variabile mensola senza farci scendere troppo in dettaglio.
[System.Diagnostics.DebuggerStepThrough()]
public Shelf()
{
_Books = new BookCollection();
}
La classe DebuggerHiddenAttribute
La classe DebuggerHiddenAttribute permette di decorare una porzione di codice per ignorarne alcuni breakpoints.
La classe DebuggerBrowsableAttribute
La classe DebuggerBrowsableAttribute ci permette di decidere se mostrare alcuni membri di una classe nelle finestre di debug dell'IDE di VS2005, prime fra tutte la Locals e la Watch. Per default, infatti, se vediamo un oggetto
in queste finestre, ne vediamo tutti i membri, siano essi privati o pubblici.
Con questo attributo, è possibile decidere di non mostrare i fields, per
esempio, oppure un proprietà pubblica che, per qualsivoglia motivo, vogliamo
nascondere. Esiste anche la variante EditorBrowsableAttribute
che, come ha detto il nostro Adrian , ci permette di nascondere un membro dall'Intellisense di VS2005, a patto però di rispettare alcuni semplici accorgimenti come indicato nel suo post.
La classe DebuggerDisplayAttribute
La classe DebuggerDisplayAttribute è molto simpatica , perchè ci permette di decidere cosa mostrare nella colonna Value delle finestre Locals e Watch. Sembrerà anche banale, però devo dire che è un bel valore aggiunto, dato che in condizioni normali debbiamo star lì ad espandere l'oggetto per leggerne un membro. La classe DebuggerDisplayAttribute ha un solo costruttore, con un solo parametro di tipo string. Tale parametro può essere:
- una stringa qualsiasi. Esempio: "Classe Shelf"
- il nome di un membro privato o pubblico della classe stessa inserito tra { e }. Esempio: "Classe Shelf {_Name}".
- il nome di un metodo (non statico) della classe. Tale metodo deve restituire un qualsiasi value-type .NET. Esempio: "{getDebuggerString()}"
Approfondisco velocemente il punto (3). Supponiamo di modificare la classe Shelf e di aggiungere un metodo getDebuggerString(), implementato in questo modo:
private string getDebuggerString()
{
string deb = (string.IsNullOrEmpty(_Name) ? "Nessun nome" : _Name) + "; N°Books = " + _Books.Count;
return (deb);
}
Non dovremmo fare altro che decorare Shelf in questo modo....
[System.Diagnostics.DebuggerDisplay("{getDebuggerString()}")]
public class Shelf
{
...
...
...
}
....per ottenere una visualizzazione nella finestra Locals così:
Ovviamente, quella stringa "Nessun nome; N°Book = 0" vale fintantochè non assegniamo qualcosa alle proprietà Name e Books della classe. La trovo davvero utile e simpatica!!!
La classe DebuggerTypeProxyAttribute
La classe DebuggerTypeProxyAttribute è una versione avanzata
rispetto a quanto implementato attraverso la DebuggerDisplayAttribute. In
pratica, ci permette di specificare una classe .NET che ha il compito di
formattare la nostra classe. Con formattare intendo dire che, ad
esempio, vogliamo demandare alla classe ViewShelf la
visualizzazione (sempre in fase di debug) della nostra classe
Shelf. Non scendo troppo nel dettaglio, perchè non l'ho provata
direttamente, per cui vi rimando direttamente alla pagina su MSDN.
La classe DebuggerVisualizerAttribute
L'ultima classe che
voglio prendere in considerazione è la DebuggerVisualizerAttribute, un "giocattolo" con il
quale mi sto davvero divertendo. Si tratta infatti di creare un viewer
customizzato per la nostra classe; tale viewer è disponibile in fase di debug, e
ci permette di visualizzare un oggetto secondo una modalità più user-friendly
rispetto a quanto fa di default VS2005. Per esempio, possiamo fare in modo che,
ogni volta che stiamo debuggando del codice che utilizzi la classe
Book, il debugger ci renda disponibile una Windows Forms creata
da noi. Faccio un esempio pratico per rendere chiara la cosa, anche se vi
preannuncio già che ho intenzione di scrivere un post dedicato perchè, come
hanno detto altri, quella dei custom visualizers è una feature di VS2005
innovativa e particolare, che è degna di nota per essere spiegata meglio in
separata sede. Ma torniamo a noi. Diamo un'occhiata allo screenshot qui
sotto:
Ho catturato questo screenshot durante il debug di codice .NET che, fra le
altre cose, istanzia 3 oggetti della classe Book. Notate la
finestra Locals, più sotto. Notate anche la piccola lente
d'ingrandimento in corrispondenza delle righe relative a l1,
l2 e l3. Quella lente indica il fatto che VS2005 riconosce la
presenza di un custom visualizer specifico per la classe Book.
In questo momento, quindi, possiamo sfogliare i membri della classe in almeno
due modi diversi: espandere l'oggetto l1, e leggere come facciamo di
solito i fields e le properties. Altrimenti, possiamo cliccare sulla lente ed
accedere alla classe tramite un custom visualizer. Il custom visualizer è un
assembly separato, che implementa una classe che eredita direttamente da
DialogDebuggerVisualizer. Il mio visualizer è una Windows Forms
che mostra le proprietà del Book, e che ci permette
anche di modificarle mentre stiamo debuggando.
Tale assembly deve essere decorata proprio dall'attributo
DebuggerVisualizerAttribute, come mostrato qui sotto:
[assembly: System.Diagnostics.DebuggerVisualizer(
typeof(BookVisualizer.DebuggerSide),
typeof(VisualizerObjectSource),
Target = typeof(Book),
Description = "Book Visualizer")]
Ripeto: si tratta ovviamente di un argomento più complesso di quanto
descritto finora, perciò aspettatevi un post separato per spiegare meglio
ciò che ho fatto. Alla prossima!