我有一个继承自
List<MagicBean>
的类。它运行良好,在所有方面都符合预期,除了一个:当我添加 [DebuggerDisplay]
属性时。尽管查看 List 具有 [DebuggerDisplay("Count = {Count}")]
的效果,但如果我将其复制并粘贴到我的列表中,我就无法在调试时直接查看我拥有的所有 MagicBean,而无需深入了解基础 -> 私有成员。
我如何才能两全其美? IE:值列中的自定义值,而 Visual Studio 没有向我隐藏我的魔豆?
您可以通过使用 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()
以在其他地方的代码中使用,在这种情况下您可以使用它。
查看 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; }
}
}
像这样使用 DebuggerDisplay 属性:
[DebuggerDisplay("ID:{ID},Customers:{Customers==null?(int?)null:Customers.Count}")]`
class Project
{
int ID{get;set;}
IList<Customer> Customers{get;set;}
}