試煉3 - Debug 時,是怎麼看內容的呢

2022 鐵人賽文 搬回點部落

完成試煉

static void Main(string[] args)
{
    var list = new List<Product>
    {
        new Product{Id=1,Tags=new List<Tag>{new Tag{Id=61,Name="TA"}},Title="PA",Price=100},
        new Product{Id=2,Tags=new List<Tag>{new Tag{Id=61,Name="TB"}},Title="PB",Price=110},
        new Product{Id=3,Tags=new List<Tag>{new Tag{Id=61,Name="TC"}},Title="PC",Price=130}
    };
}
public class Product
{
    public int Id { get; set; }
    public List<Tag> Tags { get; set; }
    public string Title { get; set; }
    public int Price { get; set; }
}

public class Tag
{
    public int Id { get; set; }
    public string Name { get; set; }
}

list 放的是class 在VS Debug 時就會看到這樣的畫面
 


還要一個一個展開才能看到內容
Product class有習慣加上

public override string ToString()
{
    return $"{Title} - {Price}";
}


就可以看到ToString的結果 不過其實VS有一個屬性 專門就是用來顯示Debug時
加上 DebuggerDisplay (nq 是 no-quotes 的意思)

[DebuggerDisplay("{Title,nq}:{Price,nq}")]
public class Product
{
    public int Id { get; set; }
    public List<Tag> Tags { get; set; }
    public string Title { get; set; }
    public int Price { get; set; }
}

那Tags怎麼呈現呢 (也可以看一下沒加上nq的樣子)
[DebuggerDisplay("{Title} - {Tags[0].Name} :{Price,nq}")]
 

如果{Tags[0].Name}改成{Tags}
[DebuggerDisplay("{Title} - {Tags} :{Price,nq}")]
{Tags} 會變成Count=1

支援一層套一層的DebuggerDisplay

[DebuggerDisplay("{Title} - {Tags[0]} :{Price,nq}")]
public class Product

[DebuggerDisplay("Tag : {Id} {Name,nq}")]
public class Tag

還有{Title} 可以玩很多變化像是
{Title.ToLower()}
{IsEmpty ? 0 : Count}

如果覺得太複雜的時候還可以這樣做

[DebuggerDisplay("{DD}")]
public class Product
{ 
    private string DD
    {
        get { return $"{Id} {Title} {Price} Tags:{Tags.Count}"; }
    }
}

延伸試煉

DebuggerTypeProxy 這我比較少用 就看下面連結吧
C# 使用 DebuggerDisplay 和 DebuggerTypeProxy 來呈現 Debugger 相關資訊

結束試煉

現在學會DebuggerDisplay看List或class就方便許多

參考
Simplify debugging with DebuggerDisplay attribute dotNET

自我試煉

寫完這篇後就順便練習 DebuggerTypeProxy
可以自己寫如何呈現展開後資訊

static void Main(string[] args)
{
    var list = new List<Product>
    {
        new Product{
            Id=1,
            Tags=new List<Tag>
            {
                new Tag{Id=61,Name="TA"},
                new Tag{Id=62,Name="TB"},
                new Tag{Id=63,Name="TC"}
            },
            Title="PA",
            Price=100},
    };
}
[DebuggerDisplay("{DD}")]
[DebuggerTypeProxy(typeof(TagDebugView))]
public class Product
{
    public int Id { get; set; }
    public List<Tag> Tags { get; set; }
    public string Title { get; set; }
    public int Price { get; set; }
    private class TagDebugView
    {
        private readonly Product _product;
        public TagDebugView(Product product)
        {
            _product = product;
        }
        [DebuggerBrowsable(DebuggerBrowsableState.Collapsed)]
        public string TDV => String.Join(",",_product.Tags.Select(x => x.Name));
    }
    private string DD
    {
        get { return $"{Id} {Title} {Price} Tags:{Tags.Count}"; }
    }
    public override string ToString()
    {
        return $"{Title} - {Price}";
    }
}
[DebuggerDisplay("Tag : {Id} {Name,nq}")]
public class Tag
{
    public int Id { get; set; }
    public string Name { get; set; }
}

如果內容有誤請多鞭策謝謝