如何使 [DebuggerDisplay] 尊重继承的类或至少使用集合?

问题描述 投票:0回答:3

我有一个继承自

List<MagicBean>
的类。它运行良好,在所有方面都符合预期,除了一个:当我添加
[DebuggerDisplay]
属性时。尽管查看 List 具有
[DebuggerDisplay("Count = {Count}")]
的效果,但如果我将其复制并粘贴到我的列表中,我就无法在调试时直接查看我拥有的所有 MagicBean,而无需深入了解基础 -> 私有成员。

我如何才能两全其美? IE:值列中的自定义值,而 Visual Studio 没有向我隐藏我的魔豆?

c# visual-studio visual-studio-2008 debugging visual-studio-2008-sp1
3个回答
12
投票

您可以通过使用 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>
{}

当您将鼠标悬停在 Visual Studio 中继承的列表的实例上时,这将为您提供“Count = 3”消息,并且当您展开根节点时,将提供列表中项目的视图,而无需深入到基础节点属性。

使用

ToString()
专门获取调试输出并不是一个好方法,除非您已经覆盖
ToString()
以在其他地方的代码中使用,在这种情况下您可以使用它。


2
投票

查看 MSDN 上的“使用 DebuggerDisplay 属性”文章后,他们建议您可以重写类的 ToString() 函数作为替代选项,而不是使用 DebuggerDisplay 属性。重写 ToString() 方法也不会隐藏您的 bean。

如果 C# 对象有一个被重写的 ToString(),调试器将调用 覆盖并显示其结果 标准 {} 的。 因此,如果 你已经重写了 ToString(),你确实 不必使用 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; }
    }    
}

-1
投票

像这样使用 DebuggerDisplay 属性:

[DebuggerDisplay("ID:{ID},Customers:{Customers==null?(int?)null:Customers.Count}")]`
class Project
{
    int ID{get;set;}
    IList<Customer> Customers{get;set;}
}
© www.soinside.com 2019 - 2024. All rights reserved.