簡體   English   中英

是否可以在 DebuggerDisplay 中使用條件?

[英]Is it possible to use conditions in a DebuggerDisplay?

考慮以下類:

[DebuggerDisplay("{GetType().Name,nq}: FileName = {FileName,nq}")]
public class FileWrapper
{
    public string FileName { get; set; }
    public bool IsTempFile { get; set; }
    public string TempFileName { get; set; }
}

我想添加一個基於IsTempFileName屬性的調試器顯示。 當實例是臨時文件時, TempFileName = {TempFileName,nq}我想添加字符串, TempFileName = {TempFileName,nq} 我將如何實現這一目標?

您可以使用條件運算符 (?:)

[DebuggerDisplay("{GetType().Name,nq}: FileName = {FileName,nq}{IsTempFile ? \", TempFileName: \" + TempFileName : System.String.Empty,nq}")]

IsTempFile == false

在此處輸入圖片說明


IsTempFile == true

在此處輸入圖片說明

您可以使用任何有效的表達式。

但是,請記住,調試器會對這些表達式進行大量計算,因此您使它們越復雜,您就越會注意到調試速度降低(例如,在單步執行代碼時)。

另一個要考慮的主要事情是表達式由使用類的語言的調試器評估。 如果該類及其所有潛在用戶都使用 C#,則沒有問題,您可以使用三元運算符之類的東西。 但是,如果您的課程也用於其他語言,則:

  1. 不能保證調試器甚至會使用 [DebuggerDisplay] 屬性,
  2. 如果是,則不能保證它會嘗試評估 {expression} 塊,並且
  3. 如果您開始做任何花哨的事情(例如使用 ?:),它很有可能無法評估您的 C# 表達式

最安全的做法是添加一個私有屬性來計算調試器值:

[DebuggerDisplay("{DebugValue,nq}")]
public class FileWrapper {

  public string FileName     { get; set; }
  public bool   IsTempFile   { get; set; }
  public string TempFileName { get; set; }

  private string DebugValue {
    get {
      var text = string.Format("{0}: FileName={1}", this.GetType(), this.FileName);
      if (this.IsTempFile)
        text += string.Format(", TempFileName={0}", this.TempFileName);
      return text;
    }
  }

}

它是私有財產,因此不會妨礙任何潛在的子類。

首先,在我的回答之前給“懶惰”的答案投票……因為他們讓我朝着正確的方向前進。

其次,這是一篇文章:

https://devblogs.microsoft.com/visualstudio/customize-object-displays-in-the-visual-studio-debugger-your-way/

下面是文章和作者的名字,以防上面的鏈接將來失效。

在 Visual Studio 調試器中以您的方式自定義對象顯示

萊斯利·理查森

程序經理,Visual Studio 調試和診斷

第三,這是一個基於 null 或非 null 子集合的稍微更通用的示例:

[System.Diagnostics.DebuggerDisplay("ParentName = '{ParentName}', MyKidsCount='{null == MyKids ? 0 : MyKids.Count}'")]
public class MyParent
{
    public string ParentName { get; set; }

    public ICollection<MyKid> MyKids { get; set; }
}

您可以將它與 Extensions 方法一起使用。

using System;
using System.Linq;
using System.Diagnostics;
using System.ComponentModel;

namespace ConsoleApplicationDebuggerDisplay
{
    class Program
    {
        static void Main(string[] args)
        {
            MyObject o1 = new MyObject();
            MyObject o2 = new MyObject();
            o1.Items = new int[] { 1, 2, 3, 4 };
        }
    }

    [DebuggerDisplay("{DebuggerDisplay,nq}")]
    public class MyObject
    {
        [DebuggerDisplay("{Items.ToDebuggerDisplay(),nq}")]
        public int[] Items { get; set; }

        [DebuggerBrowsable(DebuggerBrowsableState.Never), Browsable(false)]
        internal string DebuggerDisplay
        {
            get
            {
                return string.Format("{{Items={0} ...}}"
                    , Items.ToDebuggerDisplay()
                    );
            }
        }
    }

    internal static class Extensions
    {
        public static bool IsNull(this object o)
        {
            return object.ReferenceEquals(o, null);
        }

        public static bool IsNotNull(this object o)
        {
            return !object.ReferenceEquals(o, null);
        }

        public static string ToDebuggerDisplay<T>(this System.Collections.Generic.IEnumerable<T> items)
        {
            if (items.IsNull())
                return "null";
            return string.Format("{{Count={0}}}", items.Count());
        }
    }
}

手表

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM