我有一个继承自 List<MagicBean>
的类。它在所有方面都表现良好,并如预期一样,唯一的问题是添加了 [DebuggerDisplay]
属性后出现了异常。即使我将其复制并粘贴到我的类中,仅这样就会导致在调试时不能直接查看所有 MagicBeans,而需要钻入基类和私有成员。
该如何既实现自定义值列,又不影响 Visual Studio 在调试时显示我的 Magic Beans?
我有一个继承自 List<MagicBean>
的类。它在所有方面都表现良好,并如预期一样,唯一的问题是添加了 [DebuggerDisplay]
属性后出现了异常。即使我将其复制并粘贴到我的类中,仅这样就会导致在调试时不能直接查看所有 MagicBeans,而需要钻入基类和私有成员。
该如何既实现自定义值列,又不影响 Visual Studio 在调试时显示我的 Magic Beans?
通过使用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()
以供您的代码使用,在这种情况下,您可以利用它。
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("ID:{ID},Customers:{Customers==null?(int?)null:Customers.Count}")]`
class Project
{
int ID{get;set;}
IList<Customer> Customers{get;set;}
}