Utilizzo dell'attributo DebuggerDisplay
Le informazioni contenute in questo argomento sono valide per:
Edizione |
Visual Basic |
C# |
F# |
C++ |
Web Developer |
---|---|---|---|---|---|
Express |
|||||
Pro, Premium e Ultimate |
L'attributo DebuggerDisplay (System.Diagnostics.DebuggerDisplayAttribute) controlla la modalità di visualizzazione di una classe o di un campo nelle finestre delle variabili del debugger. Questo attributo può essere applicato a:
Classi
Strutture
Delegati
Enumerazioni
Campi
Proprietà
Assembly
L'attributo DebuggerDisplay presenta un solo argomento, costituito da una stringa da visualizzare nella colonna Valore per le istanze del tipo. Questa stringa può contenere parentesi graffe ({ e }). Il testo racchiuso tra due parentesi graffe verrà valutato come un campo, una proprietà o un metodo.
Se un oggetto C# ha un metodo ToString() sottoposto a override, il debugger chiamerà l'override e ne visualizzerà il risultato, anziché chiamare il metodo {<typeName>} standard. Pertanto, se si è eseguito l'override del metodo ToString(), non è necessario utilizzare l'attributo DebuggerDisplay. Se si utilizzano entrambi, l'attributo DebuggerDisplay avrà la precedenza sull'override di ToString().
La valutazione da parte del debugger di questa chiamata implicita a ToString() dipende da un'impostazione utente nella finestra di dialogo Opzioni (categoria Debug, pagina Generale). In Visual Basic questa valutazione implicita di ToString() non è implementata.
Importante |
---|
Se la casella di controllo Mostra struttura non elaborata degli oggetti nelle finestre delle variabili è selezionata nella finestra di dialogo Strumenti Opzioni, l'attributo DebuggerDisplay viene ignorato. |
Nella tabella riportata di seguito vengono visualizzati alcuni utilizzi possibili dell'attributo DebuggerDisplay e alcuni output di esempio.
Attribute |
Output visualizzato nella colonna Valore |
---|---|
[DebuggerDisplay("x = {x} y = {y}")] Utilizzato in un tipo con campi x e y. |
x = 5 y = 18 |
[DebuggerDisplay("String value is {getString()}")] La sintassi del parametro può variare a seconda del linguaggio. Prestare, pertanto, particolare attenzione. |
String value is [5, 6, 6] |
DebuggerDisplay può anche accettare parametri denominati.
Parametri |
Scopo |
---|---|
Name, Type |
Questi parametri influiscono sulle colonne Nome e Tipo delle finestre delle variabili. Possono essere impostati su stringhe con la stessa sintassi del costruttore. L'utilizzo eccessivo o improprio di questi parametri può generare confusione nell'output. |
Target, TargetTypeName |
Specifica il tipo di destinazione quando l'attributo viene utilizzato a livello di assembly. |
Nota
Il file autoexp.cs utilizza l'attributo DebuggerDisplay a livello di assembly. Il file autoexp.cs determina le espansioni predefinite utilizzate da Visual Studio per le variabili C#. È possibile esaminare il file autoexp.cs per esempi di utilizzo dell'attributo DebuggerDisplay o è possibile modificare e compilare il file autoexp.cs per modificare le espansioni predefinite. Assicurarsi di eseguire un backup del file autoexp.cs prima di modificarlo. È necessario fare riferimento a Microsoft.VisualStudio.DebuggerVisualizers.dll in \Program Files\Microsoft Visual Studio 10.0\Common7\IDE\PublicAssemblies. È possibile trovare il file autoexp.cs in My Documents/Visual Studio 10.0/Visualizers.
Utilizzo di espressioni in DebuggerDisplay
Sebbene sia possibile utilizzare un'espressione generale tra parentesi in un attributo DebuggerDisplay, questa procedura non è consigliata.
Espressione generale in DebuggerDisplay ha accesso implicito al puntatore this solo per l'istanza corrente del tipo di destinazione. L'espressione non ha accesso ad alias, variabili locali o puntatori. Se l'espressione fa riferimento a proprietà, gli attributi su tali proprietà non vengono elaborati. Ad esempio, il codice C# [DebuggerDisplay("Object {count - 2}" visualizza Object 6 se il campo count è 8.
L'utilizzo di espressioni in DebuggerDisplay può condurre ai problemi seguenti:
La valutazione delle espressioni è l'operazione più dispendiosa nel debugger e viene valutata ogni volta che viene visualizzata. Ciò può causare problemi di prestazioni nell'esecuzione di istruzioni a livello di codice. Ad esempio, un'espressione complessa che viene utilizzata per visualizzare i valori in un insieme o in un elenco può essere molto lenta quando esiste un grande numero di elementi.
Le espressioni vengono valutate dall'analizzatore di espressioni del linguaggio dello stack frame corrente e non dall'analizzatore del linguaggio in cui l'espressione è stata scritta. Questa situazione può provocare risultati imprevisti quando i linguaggi sono diversi.
La valutazione dell'espressione può modificare lo stato dell'applicazione. Ad esempio, un'espressione che imposta il valore di una proprietà modifica il valore della proprietà nel codice in esecuzione.
Un modo per ridurre i possibili problemi della valutazione dell'espressione è creare una proprietà privata che esegue l'operazione e restituisce una stringa. L'attributo DebuggerDisplay può visualizzare il valore di tale proprietà privata. Nell'esempio seguente viene implementato questo modello:
[DebuggerDisplay("{DebuggerDisplay,nq}")]
public sealed class MyClass {
public int count { get; set; }
public bool flag { get; set; }
private string DebuggerDisplay {
get{ return string.Format("("Object {0}", count - 2); }
}
}
Esempio
Nell'esempio di codice seguente viene illustrato l'utilizzo di DebuggerDisplay, insieme a DebuggerBrowseable e DebuggerTypeProxy. Quando visualizzato in una finestra delle variabili del debugger, come la finestra Espressioni di controllo, produce un'espansione analoga alla seguente:
Nome |
Value |
Digitare |
---|---|---|
Key |
"three" |
oggetto {string} |
Value |
3 |
oggetto {int} |
[DebuggerDisplay("{value}", Name = "{key}")]
internal class KeyValuePairs
{
private IDictionary dictionary;
private object key;
private object value;
public KeyValuePairs(IDictionary dictionary, object key, object value)
{
this.value = value;
this.key = key;
this.dictionary = dictionary;
}
public object Key
{
get { return key; }
set
{
object tempValue = dictionary[key];
dictionary.Remove(key);
key = value;
dictionary.Add(key, tempValue);
}
}
public object Value
{
get { return this.value; }
set
{
this.value = value;
dictionary[key] = this.value;
}
}
}
[DebuggerDisplay("{DebuggerDisplay,nq}")]
[DebuggerTypeProxy(typeof(HashtableDebugView))]
class MyHashtable
{
public Hashtable hashtable;
public MyHashtable()
{
hashtable = new Hashtable();
}
private string DebuggerDisplay
{
get { return "Count = " + hashtable.Count); }
}
private class HashtableDebugView
{
private MyHashtable myhashtable;
public HashtableDebugView(MyHashtable myhashtable)
{
this.myhashtable = myhashtable;
}
[DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
public KeyValuePairs[] Keys
{
get
{
KeyValuePairs[] keys = new KeyValuePairs[myhashtable.hashtable.Count];
int i = 0;
foreach (object key in myhashtable.hashtable.Keys)
{
keys[i] = new KeyValuePairs(myhashtable.hashtable, key, myhashtable.hashtable[key]);
i++;
}
return keys;
}
}
}
}
Vedere anche
Riferimenti
Utilizzo dell'attributo DebuggerTypeProxy
Concetti
Visualizzazione di tipi di dati personalizzati
Miglioramento del debug tramite gli attributi di visualizzazione del debugger
Cronologia delle modifiche
Data |
Cronologia |
Motivo |
---|---|---|
Maggio 2011 |
Sono stati aggiunti avvisi relativi all'utilizzo delle espressioni nei valori dell'attributo. |
Miglioramento delle informazioni. |