1. 程式人生 > 其它 >VisualStudio 在 DebuggerDisplay 的屬性更改業務邏輯將會讓除錯和非除錯下邏輯不同

VisualStudio 在 DebuggerDisplay 的屬性更改業務邏輯將會讓除錯和非除錯下邏輯不同

本文記錄我寫的逗比程式碼,我在 DebuggerDisplay 對應的屬性的 get 方法上,在這個方法裡面修改了業務邏輯,如修改介面元素,此時我在 VisualStudio 斷點除錯下和非斷點除錯下的行為不相同

在 VisualStudio 偵錯程式進入斷點,預設開啟隱函式求值,將會自動呼叫對應的型別的 DebuggerDisplay 特性裡面說明的輸出方法,如果對應的物件沒有定義 DebuggerDisplay 特性,預設將會呼叫 ToString 方法。無論是在 DebuggerDisplay 特性還是在 ToString 方法裡面編寫變更業務邏輯的程式碼,都會讓在斷點除錯下和非斷點除錯下的行為不相同

如以下程式碼,我的 xaml 介面如下

<Window x:Class="NearberjalnodarGahayjekuqi.MainWindow"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
          xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
          xmlns:local="clr-namespace:NearberjalnodarGahayjekuqi"
          mc:Ignorable="d"
          Title="MainWindow" Height="450" Width="800">
  <Grid>
    <StackPanel x:Name="StackPanel">
    
    </StackPanel>
  </Grid>
</Window>

接下來在後臺程式碼新增一個屬性,用來在除錯時輸出

        public string Debug
        {
            get
            {
                StackPanel.Children.Add(new TextBlock()
                {
                    Text = "123"
                });
                return "Foo";
            }
        }

在 MainWindow 新增 DebuggerDisplay 特性,程式碼如下

    [DebuggerDisplay("{" + nameof(Debug) + "}")]
    public partial class MainWindow : Window
    {

    }

再寫一點程式碼,用來新增斷點

    [DebuggerDisplay("{" + nameof(Debug) + "}")]
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            Foo();
        }

        private async void Foo()
        {
            while (true)
            {
                await Task.Delay(1000);

            }
        }

        public string Debug
        {
            get
            {
                StackPanel.Children.Add(new TextBlock()
                {
                    Text = "123"
                });
                return "Foo";
            }
        }
    }

在 Foo 方法裡面加上斷點,此時可以看到,在進入斷點時,將會讓介面新增 TextBlock 元素,如果沒有進入斷點將不會修改介面

這是因為在 DebuggerDisplay 特性裡面,將會輸出被花括號包含的屬性名對應的屬性的值。也就是對應的屬性的 get 方法將會在 VisualStudio 除錯呼叫

而如果在 get 方法編寫業務邏輯,那麼呼叫 get 的次數將會和斷點進入次數相關,或和具體獲取屬性的次數相關

更多的程式碼細節還請到 githubgitee 上閱讀程式碼

可以通過如下方式獲取本文的原始碼,先建立一個空資料夾,接著使用命令列 cd 命令進入此空資料夾,在命令列裡面輸入以下程式碼,即可獲取到本文的程式碼

git init
git remote add origin https://gitee.com/lindexi/lindexi_gd.git
git pull origin 8b7af3786fd9544edeb8213d23f699938d75eb44

以上使用的是 gitee 的源,如果 gitee 不能訪問,請替換為 github 的源

git remote remove origin
git remote add origin https://github.com/lindexi/lindexi_gd.git

獲取程式碼之後,進入 NearberjalnodarGahayjekuqi 資料夾