13

我有一個繼承自List<MagicBean>的類。它在所有方面都能很好地工作,除了一個:當我添加[DebuggerDisplay]屬性時。即使查看List有[DebuggerDisplay("Count = {Count}")],如果我複製並粘貼到我的上面,我就無法直接查看我擁有的所有MagicBeans,而無需在調試時鑽入基本 - >私有成員。如何使[DebuggerDisplay]尊重繼承類或至少使用集合?

我該如何得到兩全其美? IE:值列中的自定義值,並且Visual Studio不會隱藏我的魔豆嗎?

回答

9

你可以得到你需要使用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中的繼承列表的實例上時,將顯示「計數= 3」消息,並且在展開根節點時顯示列表中的項目視圖,而無需鑽取進入基礎屬性。

使用ToString()來明確得到調試輸出不是一個好方法,除非你已經覆蓋ToString()在其他地方的代碼中使用,在這種情況下你可以使用它。

+0

漂亮,是有用的,但似乎很漂亮的複製和粘貼。我現在無法測試,但有什麼方法可以使用List已經使用的代碼,或者至少能夠編寫一次通用版本?我討厭爲每個自定義容器類輸入這個。 – MighMoS 2009-07-09 13:40:28

2

在查看MSDN上的「Using DebuggerDisplay Attribute」文章後,他們建議您可以替代類的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

使用DebuggerDisplay屬性,像這樣:

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

一些更多的信息here