Usar el atributo DebuggerDisplayUsing the DebuggerDisplay Attribute

El DebuggerDisplayAttribute Class controla cómo se muestra un objeto, propiedad o campo en las ventanas de variables del depurador.The DebuggerDisplayAttribute Class controls how an object, property, or field is displayed in the debugger variable windows. Este atributo se puede aplicar a tipos, delegados, propiedades, campos y ensamblados.This attribute can be applied to types, delegates, properties, fields, and assemblies.

El atributo DebuggerDisplay tiene un argumento único, que es una cadena que se va a mostrar en la columna de valor de las instancias del tipo.The DebuggerDisplay attribute has a single argument, which is a string to be displayed in the value column for instances of the type. Esta cadena puede contener llaves ({ y }).This string can contain braces ({ and }). El texto encerrado entre llaves se evalúa como un campo, una propiedad o un método.Text within a pair of braces is evaluated as a field, property or method.

Si una clase tiene un método ToString() invalidado, el depurador usa el método invalidado en lugar del atributo {<typeName>}predeterminado.If a class has an overridden ToString() method, the debugger uses the overridden method instead of the default {<typeName>}. Por lo tanto, si invalidó el método ToString() , el depurador usa el método invalidado en lugar del atributo{<typeName>}predeterminado, y no tiene que usar DebuggerDisplay.Thus, if you have overridden the ToString() method, the debugger uses the overridden method instead of the default{<typeName>}, and you do not have to use DebuggerDisplay. Si usa ambos, el atributo DebuggerDisplay tiene prioridad sobre el método ToString() invalidado.If you use both, the DebuggerDisplay attribute takes precedence over the overridden ToString() method.

La evaluación de esta llamada implícita a ToString() por parte del depurador depende de un valor de configuración del usuario del cuadro de diálogo Herramientas / Opciones/ Depuración .Whether the debugger evaluates this implicit ToString() call depends on a user setting in the Tools / Options / Debugging dialog box . Visual Basic no implementa esta evaluación implícita de ToString() .Visual Basic does not implement this implicit ToString() evaluation.

Importante

Si la casilla Mostrar la estructura de los objetos en ventanas de variables está seleccionada en el cuadro de diálogo Herramientas / Opciones/ Depuración , se omite el atributo DebuggerDisplay .If the Show raw structure of objects in variables windows check box is selected in the Tools /Options / Debugging dialog box, then the DebuggerDisplay attribute is ignored.

En la tabla siguiente se muestran algunos posibles usos del atributo DebuggerDisplay y resultados de ejemplo.The following table shows some possible uses of the DebuggerDisplay attribute and example outputs.

AtributoAttribute Resultado que aparece en la columna valorOutput appearing in the Value column
[DebuggerDisplay("x = {x} y = {y}")]

Se utiliza en un tipo con campos x y y.Used on a type with fields x and y.
x = 5 y = 18
La sintaxis del parámetro[DebuggerDisplay("String value is {getString()}")]puede variar según el lenguaje.[DebuggerDisplay("String value is {getString()}")]Parameter syntax can vary between languages. Por consiguiente, utilícela con cuidado.Therefore, use it with care. String value is [5, 6, 6]

DebuggerDisplay también puede aceptar parámetros con nombre.DebuggerDisplay can also accept named parameters.

ParámetrosParameters PropósitoPurpose
Name, TypeName, Type Estos parámetros afectan a las columnas Nombre y Tipo de las ventanas de variables.These parameters affect the Name and Type columns of the variable windows. (Se pueden establecer en cadenas mediante la misma sintaxis que el constructor). El uso excesivo o incorrecto de estos parámetros puede generar resultados confusos.(They can be set to strings using the same syntax as the constructor.)Overusing these parameters, or using them incorrectly, can cause confusing output.
Target, TargetTypeNameTarget, TargetTypeName Especifica el tipo de destino cuando se utiliza el atributo en el nivel de ensamblado.Specifies the target type when the attribute is used at the assembly level.

El archivo autoexp.cs usa el atributo DebuggerDisplay en el nivel de ensamblado.The autoexp.cs file uses the DebuggerDisplay attribute at the assembly level. El archivo autoexp.cs determina las expansiones predeterminadas que usa Visual Studio para los objetos .NET.The autoexp.cs file determines the default expansions that Visual Studio uses for .NET objects. Puede examinar el archivo autoexp.cs para ver ejemplos de cómo usar el atributo DebuggerDisplay, o puede modificar y compilar el archivo autoexp.cs para cambiar las expansiones predeterminadas.You can examine the autoexp.cs file for examples of how to use the DebuggerDisplay attribute, or you can modify and compile the autoexp.cs file to change the default expansions. Asegúrese de hacer un copia de seguridad del archivo autoexp.cs antes de modificarlo.Be sure to back up the autoexp.cs file before you modify it.

Para compilar autoexp.cs, abra un Símbolo del sistema para desarrolladores para VS2015 y ejecute los siguientes comandos.To build autoexp.cs, open up a Developer Command Prompt for VS2015, and run the following commands

cd <directory containing autoexp.cs>  
csc /t:library autoexp.cs  

Los cambios de autoexp.dll se recogerán en la siguiente sesión de depuración.The changes to autoexp.dll will be picked up in the next debug session.

Utilizar expresiones en DebuggerDisplayUsing Expressions in DebuggerDisplay

Aunque puede utilizar una expresión general entre llaves en un atributo DebuggerDisplay, esta práctica no es recomendable.Although you can use a general expression between the braces in a DebuggerDisplay attribute, this practice is not recommended.

Una expresión general en DebuggerDisplay tiene acceso implícito al puntero this solo para la instancia actual del tipo de destino.A general expression in DebuggerDisplay has implicit access to the this pointer for the current instance of the target type only. La expresión no tiene acceso a los alias, variables locales ni punteros.The expression has no access to aliases, locals, or pointers. Si la expresión hace referencia a propiedades, no se procesan los atributos en dichas propiedades.If the expression references properties, attributes on those properties are not processed. Por ejemplo, el código de C# [DebuggerDisplay("Object {count - 2}")] mostraría Object 6 si el campo count fuera 8.For example, the C# code [DebuggerDisplay("Object {count - 2}")] would display Object 6 if the field count was 8.

El uso de expresiones en DebuggerDisplay puede causar los siguientes problemas:Using expressions in DebuggerDisplay can lead to the following issues:

  • La evaluación de expresiones es la operación más costosa del depurador y la expresión se evalúa cada vez que se muestra.Evaluating expressions is the most expensive operation in the debugger and the expression is evaluated each time it is displayed. Esto puede causar problemas de rendimiento al recorrer el código.This can cause performance issues in stepping through code. Por ejemplo, una expresión compleja que se usa para mostrar los valores de una colección o lista puede ser muy lenta si incluye un número elevado de elementos.For example, a complex expression that is used to display the values in a collection or list can be very slow when the number of elements is large.

  • Las expresiones las evalúa el evaluador de expresiones del lenguaje del marco de pila actual, no el evaluador del lenguaje en el que se escribió la expresión.Expressions are evaluated by the expression evaluator of the language of the current stack frame and not by the evaluator of the language in which the expression was written. Esto puede provocar resultados imprevisibles cuando los lenguajes son distintos.This can cause unpredictable results when the languages are different.

  • La evaluación de una expresión puede cambiar el estado de la aplicación.Evaluating an expression can change the state of the application. Por ejemplo, una expresión que establece el valor de una propiedad muta el valor de la propiedad en el código en ejecución.For example, an expression that sets the value of a property mutates the property value in the executing code.

    Una forma de reducir los posibles problemas de la evaluación de expresiones es crear una propiedad privada que realice la operación y devuelva una cadena.One way to reduce the possible problems of expression evaluation is by creating a private property that performs the operation and returns a string. A continuación, el atributo DebuggerDisplay puede mostrar el valor de dicha propiedad privada.The DebuggerDisplay attribute can then display the value of that private property. En el ejemplo siguiente se implementa este patrón:The following example implements this pattern:

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

El ", nq" sufijo indica el evaluador de expresiones para quitar las comillas al mostrar el valor final (nq no = comillas).The ",nq" suffix tells the expression evaluator to remove the quotes when displaying the final value (nq = no quotes).

EjemploExample

En el ejemplo de código siguiente se muestra cómo utilizar DebuggerDisplay, junto con DebuggerBrowseable y DebuggerTypeProxy.The following code example shows how to use DebuggerDisplay, together with DebuggerBrowseable and DebuggerTypeProxy. Cuando se ve en una ventana de variables del depurador, como la ventana Inspección , genera una expansión similar a la siguiente:When viewed in a debugger variables window, such as the Watch window, it produces an expansion that looks like this:

NameName ValorValue TypeType
KeyKey "three""three" object {string}object {string}
ValorValue 33 object {int}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;  
            }  
        }  
    }  
}  

Vea tambiénSee Also

Usar el atributo DebuggerTypeProxy Using DebuggerTypeProxy Attribute
Crear vistas personalizadas de objetos administrados Create custom views of managed objects
Especificadores de formato en C# Format specifiers in C#
Mejorar la depuración con los atributos de visualización del depuradorEnhancing Debugging with the Debugger Display Attributes