Как заставить [DebuggerDisplay] уважать унаследованные классы или хотя бы работать с коллекциями? - PullRequest
14 голосов
/ 09 июля 2009

У меня есть класс, который наследуется от List<MagicBean>. Он работает хорошо и, как и ожидалось, во всех отношениях, кроме одного: когда я добавляю атрибут [DebuggerDisplay]. Несмотря на то, что просмотр List имеет значение [DebuggerDisplay("Count = {Count}")], если я копирую и вставляю его в свой файл, я теряю возможность просматривать все имеющиеся у меня MagicBeans, не углубляясь в base-> private, во время отладки.

Как мне получить лучшее из обоих миров? IE: пользовательское значение в столбце значений, и Visual Studio не скрывает от меня мои волшебные бобы?

Ответы [ 3 ]

11 голосов
/ 09 июля 2009

Вы можете получить нужный эффект, используя атрибут DebuggerTypeProxy . Вам нужно создать класс для отладочной «визуализации» вашего унаследованного списка:

internal sealed class MagicBeanListDebugView
{
    private List<MagicBean> list;

    public MagicBeanListDebugView(List<MagicBean> list)
    {
        this.list = list;
    }

    [DebuggerBrowsable(DebuggerBrowsableState.RootHidden)]
    public MagicBean[] Items{get {return list.ToArray();}}
}

Затем вы можете объявить этот класс для использования отладчиком для отображения вашего класса вместе с атрибутом DebuggerDisplay:

[DebuggerDisplay("Count = {Count}")]
[DebuggerTypeProxy(typeof(MagicBeanListDebugView))]
public class MagicBeanList : List<MagicBean>
{}

Это даст вам сообщение «Количество = 3», когда вы наводите курсор мыши на экземпляр вашего унаследованного списка в Visual Studio, и представление элементов в списке при развертывании корневого узла, без необходимости углубляться в базовые свойства.

Использование ToString() для получения отладочной информации не является хорошим подходом, если, конечно, вы уже не переопределите ToString() для использования в своем коде где-то еще, и в этом случае вы можете использовать его.

3 голосов
/ 09 июля 2009

Посмотрев статью " Использование атрибута DebuggerDisplay " на MSDN, они предложили переопределить функцию ToString () вашего класса в качестве альтернативного параметра вместо использования атрибута DebuggerDisplay. Переопределение метода ToString () также не скроет ваши bean-компоненты.

Если объект C # имеет переопределенный ToString (), отладчик вызовет переопределите и покажите его результат стандарта {}. Таким образом, если вы переопределили ToString (), вы делаете не обязательно использовать DebuggerDisplay. Если вы используете оба, DebuggerDisplay атрибут имеет приоритет над Переопределение ToString ().

Вы можете переопределить метод ToString () в своем классе или используете его для других целей?

Я не знаю, рассматривали ли вы это уже или нет, но я подумал, что я бы предложил, просто если это поможет. : -)

Для полноты, чтобы кто-нибудь еще мог быстро смоделировать это; Вот небольшой пример, который я сделал:

namespace StackOverflow
{
    //broken BeanPouch class that uses the DebuggerDisplay attribute
    [System.Diagnostics.DebuggerDisplay("Count = {Count}")]
    class BrokenBeanPouch : List<MagicBean>
    { }

    //working BeanPouch class that overrides ToString
    class WorkingBeanPouch : List<MagicBean>
    {
        public override string ToString()
        {
            return string.Format("Count = {0}", this.Count);
        }
    }

    class Program
    {
        static WorkingBeanPouch myWorkingBeans = new WorkingBeanPouch()
        {
            new MagicBean() { Value = 4.99m }, new MagicBean() { Value = 5.99m }, new MagicBean() { Value = 3.99m }
        };

        static BrokenBeanPouch myBrokenBeans = new BrokenBeanPouch()
        {
            new MagicBean() { Value = 4.99m }, new MagicBean() { Value = 5.99m }, new MagicBean() { Value = 3.99m }
        };

        static void Main(string[] args)
        {
            //break here so we can watch the beans in the watch window
            System.Diagnostics.Debugger.Break();
        }
    }

    class MagicBean
    {
        public decimal Value { get; set; }
    }    
}
0 голосов
/ 15 августа 2016

Используйте атрибут DebuggerDisplay так:

[DebuggerDisplay("ID:{ID},Customers:{Customers==null?(int?)null:Customers.Count}")]`
class Project
{
    int ID{get;set;}
    IList<Customer> Customers{get;set;}
}

Дополнительная информация здесь .

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