Freigeben über


Verwenden des DebuggerDisplay-Attributs

Dieses Thema gilt für folgende Anwendungsbereiche:

Edition

Visual Basic

C#

F#

C++

Web Developer

Express

Thema ist vorhanden Thema ist vorhanden Thema ist vorhanden Thema ist vorhanden Thema ist vorhanden

Pro, Premium und Ultimate

Thema ist vorhanden

Thema ist vorhanden

Thema ist vorhanden

Thema ist vorhanden

Thema ist vorhanden

Das DebuggerDisplay-Attribut (System.Diagnostics.DebuggerDisplayAttribute) steuert die Anzeige einer Klasse oder eines Felds in den Debuggervariablenfenstern. Mögliche Zuweisungen dieses Attributs:

  • Klassen

  • Strukturen

  • Delegaten

  • Enumerationen

  • Felder

  • Eigenschaften

  • Assemblys

Das DebuggerDisplay-Attribut verfügt über ein einziges Argument, das als Zeichenfolge in der Spalte Wert für Instanzen des Typs angezeigt wird Diese Zeichenfolge kann Klammern ({ und }) enthalten. Text innerhalb eines Paares geschweifter Klammern wird als ein Feld, eine Eigenschaft oder eine Methode ausgewertet.

Wenn bei einem C#-Objekt ToString() überschrieben wurde, ruft der Debugger die Überschreibung auf und zeigt deren Ergebnisse anstelle des Standardwerts {<typeName>} an. Wenn Sie also ToString() überschrieben haben, müssen Sie DebuggerDisplay nicht verwenden. Wenn Sie beides verwenden, hat das DebuggerDisplay-Attribut Vorrang gegenüber der ToString()-Überschreibung.

Ob der Debugger diesen impliziten ToString() -Aufruf auswertet, hängt von einer Benutzereinstellung im Dialogfeld Optionen ab (Kategorie Debuggen, Seite Allgemein). Visual Basic implementiert diese implizite ToString()-Auswertung nicht.

Wichtig

Wenn das Kontrollkästchen Unformatierte Struktur von Objekten in Variablenfenstern anzeigen im Dialogfeld Extras/Optionen aktiviert ist, wird das DebuggerDisplay-Attribut ignoriert.

In der folgenden Tabelle werden einige Verwendungsmöglichkeiten des DebuggerDisplay-Attributs sowie Beispielausgaben gezeigt.

Attribute

Ausgabe (angezeigt in der Spalte Wert)

[DebuggerDisplay("x = {x} y = {y}")]

Angewendet auf einen Typ mit den Feldern x und y.

x = 5 y = 18

[DebuggerDisplay("String value is {getString()}")]

Die Parametersyntax kann je nach Sprache unterschiedlich sein. Achten Sie deshalb besonders auf die Syntax.

String value is [5, 6, 6]

DebuggerDisplay kann auch benannte Parameter akzeptieren.

Parameter

Zweck

Name, Type

Diese Parameter beeinflussen die Spalte Name und die Spalte Typ der Variablenfenster. (Sie können mit derselben Syntax wie der Konstruktor auf Zeichenfolgen festgelegt werden.)

Der übermäßige Gebrauch dieser Parameter oder ihr falscher Einsatz kann zu verwirrenden Ausgaben führen.

Target, TargetTypeName

Gibt den Zieltyp an, wenn das Attribut auf Assemblyebene verwendet wird.

Tipp

Die Datei autoexp.cs verwendet das DebuggerDisplay-Attribut auf Assemblyebene. Die Datei autoexp.cs bestimmt die Standarderweiterungen, die Visual Studio für C#-Variablen verwendet. Suchen Sie in der Datei autoexp.cs entweder Beispiele zur Verwendung des DebuggerDisplay-Attributs, oder bearbeiten und kompilieren Sie die Datei autoexp.cs, um die Standarderweiterungen zu ändern. Erstellen Sie eine Sicherungskopie der Datei autoexp.cs, bevor Sie sie ändern. Sie müssen auf die Datei "Microsoft.VisualStudio.DebuggerVisualizers.dll" in "\Programme\Microsoft Visual Studio 10.0-\Common7\IDE\PublicAssemblies" verweisen. Die Datei "autoexp.cs" finden Sie im Verzeichnis "Meine Dokumente/Visual Studio 10.0/Visualizers".

Verwenden von Ausdrücken in DebuggerDisplay

Obwohl ein allgemeiner Ausdruck zwischen den geschweiften Klammern in einem DebuggerDisplay-Attribut verwendet werden kann, wird diese Vorgehensweise nicht empfohlen.

Ein allgemeiner Ausdruck in DebuggerDisplay verfügt über impliziten Zugriff auf den this-Zeiger nur für die aktuelle Instanz des Zieltyps. Der Ausdruck hat keinen Zugriff auf Aliase, lokale Variablen oder Zeiger. Wenn der Ausdruck auf Eigenschaften verweist, werden deren Attribute nicht verarbeitet. Beispielsweise würde der C#-Code [DebuggerDisplay("Object {count - 2}" den Wert Object 6 anzeigen, wenn das Feld count 8 wäre.

Verwenden von Ausdrücken in DebuggerDisplay kann zu folgenden Problemen führen:

  • Das Auswerten von Ausdrücken ist der aufwändigste Vorgang im Debugger, und der Ausdruck wird bei jedem Anzeigen ausgewertet. Dies kann Leistungsprobleme verursachen, während der Code schrittweise durchlaufen wird. Beispielsweise kann ein komplexer Ausdruck, der zum Anzeigen der Werte in einer Auflistung oder Liste verwendet wird, sehr langsam sein, wenn die Anzahl der Elemente groß ist.

  • Ausdrücke werden von der Ausdrucksauswertung der Sprache des aktuellen Stapelrahmens und nicht von der Auswertung der Sprache ausgewertet, in der der Ausdruck geschrieben wurde. Dies kann unvorhersehbare Ergebnisse zur Folge haben, wenn die Sprachen unterschiedlich sind.

  • Durch Auswerten eines Ausdrucks kann der Zustand der Anwendung geändert werden. Beispielsweise ändert ein Ausdruck, der den Wert einer Eigenschaft festlegt, den Eigenschaftswert im ausgeführten Code.

Eine Möglichkeit, die möglichen Probleme der Ausdrucksauswertung zu verringern, ist das Erstellen einer privaten Eigenschaft, die den Vorgang ausführt und eine Zeichenfolge zurückgibt. Das DebuggerDisplay-Attribut kann dann den Wert dieser privaten Eigenschaft anzeigen. Im folgenden Beispiel wird dieses Muster implementiert:

[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); }
    }
}

Beispiel

Im folgenden Codebeispiel wird veranschaulicht, wie DebuggerDisplay zusammen mit DebuggerBrowseable und DebuggerTypeProxy verwendet wird. Bei der Anzeige in einem Debuggervariablenfenster (z. B. im Fenster Überwachen) wird dadurch eine Erweiterung produziert, die folgendermaßen aussieht:

Name

Value

type

Schlüssel

"three"

object {string}

Value

3

object {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;
            }
        }
    }
}

Siehe auch

Referenz

Verwenden des DebuggerTypeProxy-Attributs

Konzepte

Anzeigen von benutzerdefinierten Datentypen

Verbessern des Debuggens mit den Debuggeranzeigeattributen

Änderungsprotokoll

Datum

Versionsgeschichte

Grund

Mai 2011

Warnungen zur Verwendung von Ausdrücken in Attributwerten wurden hinzugefügt.

Informationsergänzung.