Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
De DebuggerDisplayAttribute bepaalt hoe een object, eigenschap of veld wordt weergegeven in de variabelevensters voor foutopsporingsprogramma's. Dit kenmerk kan worden toegepast op typen (klassen, structs, opsommingen, gemachtigden), maar wordt meestal alleen toegepast op klassen en structs. Als dit wordt toegepast op een basistype, is het kenmerk ook van toepassing op een subklasse.
Het kenmerk DebuggerDisplay heeft één argument. Dit is een tekenreeks die moet worden weergegeven in de waardekolom voor exemplaren van het type. Deze tekenreeks kan accolades ({ en }) bevatten. De tekst tussen accolades wordt geëvalueerd als een veld, eigenschap of methode.
Als een klasse een overschreven ToString() methode heeft, gebruikt het foutopsporingsprogramma de overschreven methode in plaats van de standaard-{<typeName>}. In dit geval hoeft u niet te gebruiken DebuggerDisplay. Als u beide gebruikt, heeft het kenmerk DebuggerDisplay voorrang boven de overschreven methode ToString(). Het kenmerk DebuggerDisplay heeft ook voorrang op de overschreven methode ToString() in een subklasse.
Of de debugger deze impliciete
Important
Als u de optie Onbewerkte structuur van objecten weergeven in variabelenvensters selecteert, wordt het DebuggerDisplay kenmerk genegeerd. Deze instelling bevindt zich in het deelvenster Extra>Opties in de sectie Alle instellingen>Debugging>Algemeen.
Important
Als u de optie Onbewerkte structuur van objecten weergeven in variabelenvensters selecteert, wordt het DebuggerDisplay kenmerk genegeerd. Deze instelling bevindt zich in het dialoogvenster Extra>Opties in de sectie Foutopsporing>Algemeen.
Note
Voor systeemeigen code wordt dit kenmerk alleen ondersteund in C++/CLI-code.
In de volgende tabel ziet u enkele mogelijke toepassingen van het DebuggerDisplay kenmerk en voorbeelduitvoer.
| Attribute | Uitvoer die wordt weergegeven in de kolom Waarde |
|---|---|
[DebuggerDisplay("x = {x} y = {y}")]Wordt gebruikt voor een type met velden x en y. |
x = 5 y = 18 |
[DebuggerDisplay("String value is {getString()}")]parametersyntaxis kan per taal verschillen. Gebruik het daarom met zorg. |
String value is [5, 6, 6] |
DebuggerDisplay kan ook benoemde parameters accepteren.
| Parameters | Purpose |
|---|---|
Name, Type |
Deze parameters beïnvloeden de kolommen Name en Type van de variabelevensters. (Ze kunnen worden ingesteld op tekenreeksen met dezelfde syntaxis als de constructor.) Als u deze parameters te veel gebruikt of onjuist gebruikt, kan dit verwarrende uitvoer veroorzaken. |
Target, TargetTypeName |
Hiermee geeft u het doeltype op wanneer het kenmerk wordt gebruikt op assemblyniveau. |
Het autoexp.cs-bestand maakt gebruik van het kenmerk DebuggerDisplay op assemblyniveau. Het autoexp.cs-bestand bepaalt de standaarduitbreidingen die Visual Studio gebruikt voor .NET-objecten. U kunt het autoexp.cs-bestand bekijken voor voorbeelden van het gebruik van het kenmerk DebuggerDisplay, of u kunt het autoexp.cs bestand wijzigen en compileren om de standaarduitbreidingen te wijzigen. Zorg ervoor dat u een back-up maakt van het autoexp.cs-bestand voordat u het wijzigt.
Als u autoexp.cs wilt maken, opent u een opdrachtprompt voor ontwikkelaars voor VS2015 en voert u de volgende opdrachten uit
cd <directory containing autoexp.cs>
csc /t:library autoexp.cs
De wijzigingen in autoexp.dll worden opgehaald in de volgende foutopsporingssessie.
Expressies gebruiken in DebuggerDisplay
Hoewel u een algemene uitdrukking tussen de accolades in een DebuggerDisplay-kenmerk kunt gebruiken, wordt deze praktijk niet aanbevolen.
Een algemene uitdrukking in DebuggerDisplay heeft impliciete toegang tot de this-pointer, enkel voor het huidige exemplaar van het doeltype. De expressie heeft geen toegang tot aliassen, lokalen of aanwijzers. Als de expressie verwijst naar eigenschappen, worden kenmerken op deze eigenschappen niet verwerkt. De C#-code [DebuggerDisplay("Object {count - 2}")] zou bijvoorbeeld Object 6 weergeven als het veld count 8 was.
Het gebruik van expressies in DebuggerDisplay kan leiden tot de volgende problemen:
Het evalueren van expressies is de duurste bewerking in het foutopsporingsprogramma en de expressie wordt elke keer dat deze wordt weergegeven geëvalueerd. Dit kan prestatieproblemen veroorzaken bij het doorlopen van code. Een complexe expressie die wordt gebruikt om de waarden in een verzameling of lijst weer te geven, kan bijvoorbeeld erg traag zijn wanneer het aantal elementen groot is.
Expressies worden geëvalueerd door de expressie-evaluator van de taal van het huidige stackframe en niet door de evaluator van de taal waarin de expressie is geschreven. Dit kan onvoorspelbare resultaten veroorzaken wanneer de talen verschillen.
Het evalueren van een expressie kan de status van de toepassing wijzigen. Een expressie waarmee bijvoorbeeld de waarde van een eigenschap wordt ingesteld, muteert de eigenschapswaarde in de uitvoercode.
Een manier om de mogelijke problemen bij de evaluatie van expressies te verminderen, is door een privé-eigenschap te creëren die de bewerking uitvoert en een tekenreeks teruggeeft. Het kenmerk DebuggerDisplay kan vervolgens de waarde van die privé-eigenschap weergeven. In het volgende voorbeeld wordt dit patroon geïmplementeerd:
[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);
}
}
}
Het achtervoegsel ',nq' vertelt de expressie-evaluator om de aanhalingstekens te verwijderen bij het weergeven van de uiteindelijke waarde (nq = geen aanhalingstekens). Zie Opmaakaanduidingen in C# voor meer informatie over formatters.
Example
In het volgende codevoorbeeld ziet u hoe u DebuggerDisplaygebruikt, samen met DebuggerBrowsable en DebuggerTypeProxy. Wanneer deze worden weergegeven in een venster met foutopsporingsprogrammavariabelen, zoals het venster Watch, wordt er een uitbreiding gegenereerd die er als volgt uitziet:
| Name | Value | Type |
|---|---|---|
| Key | "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;
}
}
}
}