Megjegyzés
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhat bejelentkezni vagy módosítani a címtárat.
Az oldalhoz való hozzáféréshez engedély szükséges. Megpróbálhatja módosítani a címtárat.
A DebuggerDisplayAttribute szabályozza, hogyan jelenik meg egy objektum, tulajdonság vagy mező a hibakereső változóablakaiban. Ez az attribútum alkalmazható típusokra (osztályokra, szerkezetekre, enumerálásokra, delegáltakra), de általában csak osztályokra és szerkezetekre alkalmazható. Ha egy alaptípusra alkalmazva van, az attribútum egy alosztályra is vonatkozik.
A DebuggerDisplay attribútum egyetlen argumentummal rendelkezik, amely karakterlánc, amit a típuspéldányok értékoszlopában kell megjeleníteni. Ez a sztring kapcsos zárójeleket ({ és }) tartalmazhat. A zárójelpáron belüli szöveg kiértékelése mezőként, tulajdonságként vagy metódusként történik.
Ha egy osztály felülírt ToString() metódussal rendelkezik, a hibakereső az alapértelmezett {<typeName>}helyett a felülírt metódust használja. Ebben az esetben nem kell használnia DebuggerDisplay. Ha mindkettőt használja, a DebuggerDisplay attribútum elsőbbséget élvez a felülírt ToString() metódusnál. A DebuggerDisplay attribútum elsőbbséget élvez az alosztály felülírt ToString() metódusával szemben.
Az, hogy a hibakereső kiértékeli-e ezt az implicit ToString() hívást, az Eszközök (vagy Hibakeresés) > csoportban található hibakeresési beállítástól függ.
Important
Ha a Változók ablakában az objektumok nyers szerkezetének megjelenítése lehetőséget választja, a rendszer figyelmen kívül hagyja az DebuggerDisplay attribútumot. Ez a beállítás az Eszközök>beállításai panelen, az Összes beállítás>hibakeresése>általános szakaszában található.
Important
Ha a Változók ablakában az objektumok nyers szerkezetének megjelenítése lehetőséget választja, a rendszer figyelmen kívül hagyja az DebuggerDisplay attribútumot. Ez a beállítás az Eszközök>beállításai párbeszédpanelen, a Hibakeresés>általános szakaszában található.
Note
Natív kód esetén ez az attribútum csak C++/CLI-kódban támogatott.
Az alábbi táblázat a DebuggerDisplay attribútum és a példakimenetek lehetséges használatát mutatja be.
| Attribute | Az Érték oszlopban megjelenő kimenet |
|---|---|
[DebuggerDisplay("x = {x} y = {y}")]x és ymezővel rendelkező típuson használatos. |
x = 5 y = 18 |
[DebuggerDisplay("String value is {getString()}")]Paraméterszintaxis nyelvenként eltérő lehet. Ezért óvatosan használja. |
String value is [5, 6, 6] |
DebuggerDisplay elnevezett paramétereket is elfogadhat.
| Parameters | Purpose |
|---|---|
Name, Type |
Ezek a paraméterek hatással vannak a változóablakok Név és Típus oszlopára. (A konstruktor szintaxisával megegyező szintaxist használó sztringekre állíthatók be.) Ezeknek a paramétereknek a túlzott használata vagy helytelen használata zavaró kimenetet okozhat. |
Target, TargetTypeName |
Megadja a céltípust, amikor az attribútumot a szerelvény szintjén használják. |
A autoexp.cs fájl a DebuggerDisplay attribútumot használja a szerelvény szintjén. A autoexp.cs fájl határozza meg a Visual Studio által a .NET-objektumokhoz használt alapértelmezett bővítéseket. Megvizsgálhatja a autoexp.cs fájlt, például a DebuggerDisplay attribútum használatát, vagy módosíthatja és lefordíthatja a autoexp.cs fájlt az alapértelmezett bővítmények módosításához. A módosítás előtt győződjön meg arról, hogy biztonsági másolatot készít a autoexp.cs fájlról.
A autoexp.cs létrehozásához nyisson meg egy fejlesztői parancssort a VS2015-höz, és futtassa a következő parancsokat
cd <directory containing autoexp.cs>
csc /t:library autoexp.cs
A autoexp.dll módosításai a következő hibakeresési munkamenetben lesznek átvéve.
Kifejezések használata a DebuggerDisplayben
Bár a DebuggerDisplay attribútum kapcsos zárójelei között általános kifejezést is használhat, ez a gyakorlat nem ajánlott.
A DebuggerDisplay általános kifejezései kizárólag a céltípus aktuális példányához rendelkeznek implicit hozzáféréssel a this mutatóhoz. A kifejezés nem fér hozzá az aliasokhoz, a helyi beállításokhoz és a mutatókhoz. Ha a kifejezés tulajdonságokra hivatkozik, a tulajdonságok attribútumai nem lesznek feldolgozva. A C#-kód [DebuggerDisplay("Object {count - 2}")] például Object 6 jelenne meg, ha a mező count 8.
Ha kifejezéseket használ a DebuggerDisplayben, az a következő problémákhoz vezethet:
A kifejezések kiértékelése a hibakereső legdrágább művelete, és a kifejezés minden megjelenítéskor kiértékelésre kerül. Ez teljesítményproblémákat okozhat a kódon való áthaladás során. Egy gyűjtemény vagy lista értékeinek megjelenítésére használt összetett kifejezés például nagyon lassú lehet, ha az elemek száma nagy.
A kifejezéseket az aktuális veremkeret nyelvének kifejezésértékelője értékeli ki, nem pedig annak a nyelvnek a kiértékelője, amelyben a kifejezést írták. Ez kiszámíthatatlan eredményeket okozhat, ha a nyelvek eltérőek.
Egy kifejezés kiértékelése megváltoztathatja az alkalmazás állapotát. Egy tulajdonság értékét állító kifejezés például a végrehajtási kódban a tulajdonság értékét mutálja.
A kifejezésértékelés lehetséges problémáinak csökkentésének egyik módja egy olyan privát tulajdonság létrehozása, amely végrehajtja a műveletet, és visszaad egy sztringet. A DebuggerDisplay attribútum ezután megjelenítheti a magántulajdonság értékét. Az alábbi példa ezt a mintát valósítja meg:
[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);
}
}
}
A ",nq" utótag azt jelzi a kifejezés kiértékelőjének, hogy távolítsa el az idézőjeleket a végső érték megjelenítésekor (nq = nincs idézőjel). A formázókkal kapcsolatos további információkért lásd a C# formátumjelölőit.
Example
Az alábbi példakód bemutatja, hogyan használható DebuggerDisplay, valamint DebuggerBrowsable és DebuggerTypeProxy. Amikor megnézi egy hibakereső változók ablakában, például a Watch ablakban, akkor a kibontás így néz ki:
| Name | Value | Type |
|---|---|---|
| Key | "three" | objektum : {string} |
| Value | 3 | objektum : {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;
}
}
}
}