14

我有一个继承自List<MagicBean>. 它运行良好并且在所有方面都符合预期,除了一个:当我添加[DebuggerDisplay]属性时。即使查看 List 具有它的 as [DebuggerDisplay("Count = {Count}")],如果我将其复制并粘贴到我的上,我将无法直接查看我拥有的所有 MagicBeans,而无需在调试时深入到 base->private 成员。

我如何获得两全其美?IE:值列中的自定义值,Visual Studio 没有对我隐藏我的魔豆?

4

3 回答 3

11

您可以通过使用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()在其他地方的代码中覆盖使用,在这种情况下您可以使用它。

于 2009-07-08T23:26:00.480 回答
2

在查看 MSDN 上的“使用 DebuggerDisplay 属性”文章后,他们建议您可以覆盖类的 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; }
    }    
}
于 2009-07-08T22:01:04.177 回答
0

像这样使用 DebuggerDisplay 属性:

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

更多信息在这里

于 2016-08-15T13:54:45.880 回答