Visual Studio 除錯技巧之即時視窗的妙用

精緻碼農發表於2020-12-02

在 Visual Studio 中有一個視窗叫 Immediate 視窗,中文版本應該叫即時視窗。預設會在你啟動除錯時在 VS 編輯器中彈出來。你也可以通過 Debug | Windows | Immediate 或者使用快捷鍵 Ctrl+Alt+I 手動把它調出來。

這個視窗很實用,尤其是在除錯的時候。下面總結幾個即時視窗的實用技巧。

1. 臨時執行C#程式碼

有時候你可能只想知道一句C#程式碼執行的結果,比如你突然想知道一個空陣列呼叫Sum()方法會不會報錯,或者想檢視一下Math.PI的值。你不用傻傻地把測試程式碼寫在專案裡,設個斷點,然後把專案跑起來檢視。你可以在即時視窗中直接寫C#程式碼,然後按回車即可。比如輸入:

Console.WriteLine("Welcome!")

回車執行:

再如,你可以直接輸入 Math.PI 等表示式和呼叫某些方法:

也可以用 VS 的另外一個視窗 View | Other Windows | C# Interactive 來實現個功能。如果只是為了臨時執行 C# 程式碼塊,則C# Interactive 會更好用些。兩者使用有些區別,C# Interactive 列印內容需要手動呼叫 Console.Write 等方法:

2. 除錯時呼叫任何方法

假如你正在除錯一個方法,你臨時測試一下這個方法對於不同的引數的執行過程或執行結果。比如對於這樣一段程式碼:

class Program
{
    static void Main(string[] args)
    {
        var foo = new Foo();
        var result = foo.Add(1, 2, 3);
        Console.WriteLine(result);
    }
}

public class Foo
{
    public int Add(params int[] nums)
    {
        if (nums?.Length < 1)
            return 0;
        var result = 0;
        foreach (var n in nums)
        {
            // ...(其它程式碼)
            result += n;
        }
        return result;
    }
}

若想用不同的引數來測試foo.Add方法的執行情況,普通的做法是啟動多次除錯,每次除錯都修改一下呼叫程式碼 foo.Add 的引數。使用即時視窗,你可以在方法呼叫處打個斷點。然後在即時視窗編寫呼叫程式碼,它會直接使用當前上下文進行除錯。不需要中斷 VS 除錯再重新啟動。

另外,在即時視窗可以呼叫私有方法,也就是說它不受方法的訪問許可權限制。

不過,在即時視窗編寫呼叫私有方法的程式碼時是沒有智慧提示的。

3. 使方法執行不影響上下文

預設情況下,在即時視窗執行的程式碼,執行完後會對上下文產生副作用(Side Effect)。比如對於這樣一段程式碼:

class Program
{
    static void Main(string[] args)
    {
        var foo = new Foo();
        Console.WriteLine();
    }
}

public class Foo
{
    public int Num { get; private set; }
    public int Increase()
    {
        return ++Num;
    }
}

在即時視窗中呼叫foo.Increase後,Num 的變化如下:

但很多時候我們只希望即使視窗只是臨時執行一下除錯程式碼,不想讓它真修改上下文的狀態。我們只需在表示式後面新增 , nse(no side effect 的簡寫)即可:

加上 nse 後,執行的那句程式碼相當於在一個沙箱中執行,和上下文互不干擾。

4. 訪問特殊變數

Visual Studio 在除錯過程中有一些特殊的變數,可以在即時視窗列印它們的值。這些特殊的變數以 $ 作為字首,通過智慧提示可以看到目前有三個這樣的特殊變數:

  • $exception,當前的異常資訊。有時候在除錯時,你程式碼的 try/catch 語句沒有給 catch 語句使用 Exception 引數,則可以在即使視窗使用該特殊變數列印異常資訊。

  • $returnvalue,當前語句的返回值。有時候你在程式碼中呼叫了一個方法,但你並沒有用一個變數來儲存這個方法的返回值,而你在除錯時又想知道它的返回值。此時你可以在方法執行處新增一個斷點。當執行到該斷點時,按 F10,然後在即時視窗可以通過 $returnvalue 列印該方法的返回值。

  • $user,可以用來獲取當前登入作業系統的使用者資訊和當前執行的程式和執行緒資訊。這個我也沒用過,官方文件介紹也比較簡單,也不知道這個特殊變數包含哪些成員。直接列印是這樣的:

結束

本文分享的這幾個即時視窗的技巧,在除錯時很實用,在工作中我經常使用,希望它也可以幫助你提高開發效率。關於除錯,VS 還有其它好用的工具或技巧,比如有一個 Watch(監視)視窗,如果除錯時要頻繁檢視一個物件的值,使用監視視窗比即時視窗方便很多。

當然,還是希望大家自己去探索更多的技巧,以做到能更高效靈活地使用 VS 這個強大的編輯器。

相關文章