Condividi tramite


Utilizzo dell'attributo DebuggerDisplay

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.

Nota importanteImportante

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.

Attributo

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 impostate in stringhe utilizzando la stessa sintassi del costruttore.) utilizzo questi parametri, o tramite in modo corretto, può generare l'output confondente.

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 11.0\Common7\IDE\PublicAssemblies.È possibile trovare il file autoexp.cs in My Documents/Visual Studio 2012/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 una raccolta 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

Valore

Type

Chiave

"three"

oggetto {string}

Valore

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