Compartilhar via


Usando o atributo DebuggerDisplay

Os controles de atributo de DebuggerDisplay ()System.Diagnostics.DebuggerDisplayAttributecomo uma classe ou um campo são exibidos nas janelas de variável do depurador.Esse atributo pode ser aplicado:

  • Classes

  • Estruturas

  • Delegados

  • Enum

  • Campos

  • Propriedades

  • Conjuntos de Módulos (Assemblies)

O atributo de DebuggerDisplay tem um único argumento, uma cadeia de caracteres a ser exibida na coluna valor de instâncias do tipo.Essa cadeia de caracteres pode conter chaves ({ e }).O texto em um par de chaves será avaliado como um campo, propriedade ou método.

Se um objeto de C# tem ToString()substituído, o depurador irá chamar a substituição e mostrará o resultado em vez de {<typeName>}padrão.Assim, se você substituiu ToString(), você não precisa usar DebuggerDisplay.Se você usar ambos, o atributo de DebuggerDisplay tem precedência sobre substituição de ToString() .

Se o depurador avalia este chamada implícita de ToString()depende de uma configuração de usuário na caixa de diálogo de Opções (categoria deDepurando , a página de Geral ).Visual Basic não implementa essa avaliação implícita de ToString() .

Observação importanteImportante

Se a caixa de seleção de Mostrar estrutura bruta de objetos nas janelas de variáveis está selecionada na caixa de diálogo de Opções de ferramentas , então o atributo de DebuggerDisplay será ignorado.

A tabela a seguir mostra alguns usos possíveis de saída do atributo e de exemplo DebuggerDisplay .

Atributo

Saída que aparecem na coluna de Valor )

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

Usado em um tipo com campos x e y.

x = 5 y = 18

a sintaxe de parâmetro de[DebuggerDisplay("String value is {getString()}")]pode variar entre linguagens.Portanto, use com cuidado.

String value is [5, 6, 6]

DebuggerDisplay também pode aceitar parâmetros nomeados.

Parâmetros

Finalidade

Name, Type

Esses parâmetros afetam as colunas de Nome e de Tipo do windows variáveis.(Podem ser definidos para as cadeias de caracteres usando a mesma sintaxe que o construtor.) usar esses parâmetros, ou usá-los incorretamente, podem causar saída confusas.

Target, TargetTypeName

Especifica o tipo de destino quando o atributo é usado no nível do assembly.

ObservaçãoObservação

O arquivo de autoexp.cs usa o atributo de DebuggerDisplay no nível do assembly.O arquivo de autoexp.cs determina o usa padrão do Visual Studio expansões das variáveis para C#.Você pode examinar o arquivo de autoexp.cs para obter exemplos de como usar o atributo de DebuggerDisplay , ou você pode alterar e compilar o arquivo de autoexp.cs para alterar as expansões padrão.Certifique-se de backup do arquivo de autoexp.cs antes que você modifique o.Você deve referenciar Microsoft.VisualStudio.DebuggerVisualizers.dll em \ program files \ Microsoft Visual Studio 11,0 \ Common7 \ IDE \ PublicAssemblies.Você pode localizar o arquivo de autoexp.cs em meus documentos/Visual Studio 2012/Visualizers.

Usando expressões em DebuggerDisplay

Embora você possa usar uma expressão geral entre chaves em um atributo de DebuggerDisplay, esta prática não é recomendada.

Uma expressão em geral DebuggerDisplay implícito tem acesso ao ponteiro de this para a instância atual do tipo de destino somente.A expressão não tem acesso ao alias, os locais, ou para ponteiros.Se as propriedades de referências de expressão, atributos em essas propriedades não são processadas.Por exemplo, o código [DebuggerDisplay("Object {count - 2}" C# exibiria Object 6 se o campo count era 8.

Usar expressões em DebuggerDisplay pode levar a problemas seguintes:

  • Avaliar expressões é a operação de obtenção mais cara no depurador e a expressão é avaliada cada vez que é exibida.Isso pode causar problemas de desempenho em avançar no código.Por exemplo, uma expressão complexa que é usada para exibir os valores em uma coleção ou em uma lista pode ser muito lento quando o número de elementos é grande.

  • Expressões são avaliadas pelo avaliador de expressão de idioma do quadro de pilha atual e não por avaliador de linguagem em que a expressão foi escrita.Isso pode causar resultados imprevisíveis quando os idiomas são diferentes.

  • Avaliar uma expressão pode alterar o estado do aplicativo.Por exemplo, uma expressão que define o valor de uma propriedade torna o valor da propriedade no código em execução.

Uma maneira para reduzir problemas possíveis de avaliação de expressão é criando uma propriedade particular que executa a operação e retorna uma cadeia de caracteres.O atributo de DebuggerDisplay pode exibir o valor da propriedade particular.O exemplo a seguir implementa esse padrão:

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

Exemplo

O exemplo de código a seguir mostra como usar DebuggerDisplay, juntamente com DebuggerBrowseable e DebuggerTypeProxy.Quando exibido em uma janela de variáveis do depurador, como a janela de Inspeção , gera uma expansão com esta aparência:

Nome

Valor

Tipo

Chave

“três”

objeto cadeia de caracteres {}

Valor

3

int objeto {}

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

Consulte também

Referência

Usando o atributo DebuggerTypeProxy

Conceitos

Exibindo tipos de dados personalizados

Aprimorando a depuração com os atributos de exibição do depurador