English version

Изменение поведения отладчика в Visual Studio

Какое неудобство настигает нас при отладке приложения в Visual Studio? Для меня всегда было неудобно осуществлять навигацию по свойствам объекта, когда нужна какая-то информация. В этой статье я приведу набор атрибутов, которые позволяют упростить данный процесс.

Для того, чтобы упростить этот процесс можно использовать набор предопределенных атрибутов.

DebuggerDisplay

Позволяет задать строку для класса или свойства, которая будет отображаться в отладчике.

public class Person
{
     public string FirstName { get; set; }

     public string LastName { get; set; }

     public int Age { get; set; }
}

По умолчанию, при просмотре значения отладчик отобразит полное название класса:

Изменение поведения отладчика в Visual Studio

Добавим атрибут DebuggerDisplay:

[DebuggerDisplay("{FirstName} {LastName}, {Age} years old")]
public class Person
{
     public string FirstName { get; set; }

     public string LastName { get; set; }

     public int Age { get; set; }
}

Тогда отображение в отладчике изменится следующим образом:

Изменение поведения отладчика в Visual Studio

Аналогичным образом можно настроить отображение значений свойств:

[DebuggerDisplay("{FirstName} {LastName}, {Age} years old")]
public class Person
{
     public string FirstName { get; set; }

     public string LastName { get; set; }

     [DebuggerDisplay("{Age} years old")]
     public int Age { get; set; }
}
Изменение поведения отладчика в Visual Studio

DebuggerBrowsable

Позволяет управлять поведением отладчика, при отображении свойства. В конструкторе должен передаваться параметр DebuggerBrowsableState, который принимает одно из следующих состояний:

На практике использование этого атрибута выглядит так:

public class Person
{
     public string FirstName { get; set; }

     public string LastName { get; set; }

     [DebuggerBrowsable(DebuggerBrowsableState.Never)]
     public int Age { get; set; }

     [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
     public string[] Phones { get; set; }
}
Изменение поведения отладчика в Visual Studio

DebuggerTypeProxy

Этот способ позволяет более радикально изменить способ отображения информации об объекте.

Для того, чтобы использовать атрибут DebuggerTypeProxy, необходимо создать класс, принимающий в конструкторе отображаемый объект. Свойства этого класса и будут отображаться в отладчике вместо оригинального класса. При этом содержимое исходного класса будет отображаться в ветке Raw View.

[DebuggerTypeProxy(typeof(PersonVisualizer))]
public class Person
{
     public string FirstName { get; set; }

     public string LastName { get; set; }

     public int Age { get; set; }
}

public class PersonVisualizer
{
     private readonly Person _person;

     public PersonVisualizer(Person person)
     {
          _person = person;
     }

     public string FullName
     {
          get { return _person.FirstName + " " + _person.LastName; }
     }
}
Изменение поведения отладчика в Visual Studio

DebuggerVisualizer

Если все предыдущие способы позволяли повлиять на отображение значения в окне самого отладчика, то этот способ позволяет определить собственный пользовательский интерфейс для отображения данных. Такой способ может быть полезен при отображении сложных типов.

Для того, чтобы воспользоваться этим способом, необходимо подключить к проекту сборку Microsoft.VisualStudio.DebuggerVisualizers.

Следующим шагом будет создание объекта, ответственного за отображение отладочной информации. Для этого нужно создать класс-наследник DialogDebuggerVisualizer. В этом классе следует переопределить метод Show, который принимает контекст для отображения окна, а также объект, позволяющий получить доступ к исходному объекту.

public class PersonVisualizer : DialogDebuggerVisualizer
{
     protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
     {

     }
}

Здесь есть одно ограничение, которое накладывается на исходный объект - он должен быть сериализуемый (помечен атрибутом Serializable), для того, чтобы его можно было переслать за рамки приложения. Внутри метода Show пишем код для создания пользовательского интерфейса и отображаем данные:

public class PersonVisualizer : DialogDebuggerVisualizer
{
     protected override void Show(IDialogVisualizerService windowService, IVisualizerObjectProvider objectProvider)
     {
          Person data = (Person)objectProvider.GetObject();

          Form form = new Form();

          form.Controls.Add(new Label
          {
               Dock = DockStyle.Top,
               Text = data.FirstName
          });

          form.Controls.Add(new Label
          {
               Dock = DockStyle.Top,
               Text = data.LastName
          });

          form.Controls.Add(new Label
          {
               Dock = DockStyle.Top,
               Text = data.Age.ToString()
          });

          windowService.ShowDialog(form);
     }
}

Последнее - сообщаем компилятору о том, какой класс отладчик может использовать для отображения информации об объекте:

[DebuggerVisualizer(typeof(PersonVisualizer))]
[Serializable]
public class Person
{
     public string FirstName { get; set; }

     public string LastName { get; set; }

     public int Age { get; set; }
}

Теперь при запуске отладчика, напротив значения появится кнопка.

Изменение поведения отладчика в Visual Studio

При нажатии на ней отобразится созданная форма.

Изменение поведения отладчика в Visual Studio

DebuggerHidden и DebuggerStepThrough

Позволяет скрыть от отладчика код при выполнении пошаговой отладки.

Если вы установите точку останова в методе, помеченноматрибутом DebuggerHidden, то точка останова не сработает. Аналогичное поведение будет при использовании команды отладчика Step Into.

При использовании атрибута DebuggerStepThrough, точки останова будут срабатывать, но команда отладчика Step Into будет игнорировать метод.

public class Person
{
     public string FirstName { get; set; }

     public string LastName { get; set; }

     public int Age { get; set; }

     [DebuggerHidden]
     public void Print()
     {
     }

     [DebuggerStepThrough]
     public void Display()
     {
     }
}

Аналогично можно работать с get- и set-методами свойств.

Conditional

Этот атрибут не относится к отладчику, а скорее влияет на компиляцию кода, но также бывает полезным при отладке.

Этим атрибутом можно разметить метод и указать некоторое условие, аналогично тому, как это делается в директивах препроцессора. Если условие сработало, то указанный метод выполнится; если нет, то метод будет исключен при компиляции кода.

Например, следующий метод будет запускаться только в случае, если приложение построено в конфигурации Debug:

public class Person
{
     public string FirstName { get; set; }

     public string LastName { get; set; }

     public int Age { get; set; }

     [Conditional("DEBUG")]
     public void Print()
     {
          Console.WriteLine(LastName);
     }
}

Существуют ограничения, которые накладываются на методы, с которыми может использоваться указанный атрибут:

Эти нехитрые инструменты позволят чувствовать себя более комфортно при отладке кода. Особенно полезно использовать данные приемы, если вы разрабатываете код, который будет повторно использоваться многократно.

Обработка стека вызова исключения .NET ← → Корректная обработка проблем аутентификации AJAX-запросов для приложений ASP.NET MVC

Добавить комментарий

Для отображения аватара испольузется Gravatar
Можно форматрировать текст при помощи Markdown