練習 - 程式碼區塊和變數範圍

已完成

程式碼區塊是定義執行路徑的一或多個 C# 陳述式。 程式碼區塊外部的陳述式會影響在執行階段執行程式碼區塊的時機、執行與否及執行頻率。 程式碼區塊的界限通常是由彎曲大括弧 {} 所定義。

除了影響執行路徑之外,程式碼區塊也會影響變數的範圍。 在此練習期間檢查的程式碼範例,可協助您了解程式碼區塊與變數範圍之間的關聯性。

程式碼區塊會影響變數宣告的範圍

變數範圍是指該變數對於應用程式中其他程式碼的可見度。 區域範圍的變數只能在其定義所在的程式碼區塊內進行存取。 如果您嘗試從程式碼區塊外存取該變數,將收到編譯器錯誤。

本單元的其餘部分會探討程式碼區塊與變數範圍之間的關聯性。

準備您的撰寫程式碼環境

本課程模組包含實際操作活動,可引導您完成建置及執行示範程式碼的程序。 建立您使用 Visual Studio Code 做為開發環境來完成這些活動。 針對這些活動使用 Visual Studio Code,可協助您更熟悉在全球專業人員使用的開發人員環境中撰寫及執行程式碼。

  1. 打開 Visual Studio Code。

    您可以使用 Windows [開始] 功能表 (或另一個作業系統的對等資源) 來開啟 Visual Studio Code。

  2. 在 Visual Studio Code 的 [檔案] 功能表上,選取 [開啟資料夾]。

  3. 在 [開啟資料夾] 對話方塊中,瀏覽至 Windows Desktop 資料夾。

    如果您在不同的資料夾位置中保留程式碼專案,您可以改用該資料夾位置。 針對本訓練,請務必使用容易找到並記住的位置。

  4. 在 [開啟資料夾] 對話方塊中,選取 [選取資料夾]。

    如果您看到詢問您是否信任作者的安全性對話方塊,請選取 [是]。

  5. 在 Visual Studio Code 的 [終端] 功能表上,選取 [新增終端]。

    請注意,終端面板中的命令提示字元會顯示目前資料夾的資料夾路徑。 例如:

    C:\Users\someuser\Desktop>
    

    注意

    如果您是在自己的電腦上工作,而不是在沙箱或託管環境中工作,且您已完成此 C# 系列中的其他 Microsoft Learn 課程模組,您可能已針對程式碼範例建立專案資料夾。 如果是這種情況,您可以略過下一個步驟,這個步驟會用來在 TestProject 資料夾中建立主控台應用程式。

  6. 在終端命令提示字元中,若要在指定的資料夾中建立新的主控台應用程式,請輸入 dotnet new console -o ./CsharpProjects/TestProject,然後按 Enter 鍵。

    這個 .NET CLI 命令會使用 .NET 程式範本,在指定的資料夾位置中建立新的 C# 主控台應用程式專案。 這個命令會為您建立 CsharpProjects 和 TestProject 資料夾,並使用 TestProject 做為 .csproj 檔案的名稱。

  7. 在 [總管] 面板中,展開 CsharpProjects 資料夾。

    您應該會看到 TestProject 資料夾和兩個檔案:名為 Program.cs 的 C# 應用程式檔案,以及名為 TestProject.csproj 的 C# 專案檔。

  8. 在 [總管] 面板中,若要在 [編輯器] 面板中檢視程式碼檔案,請選取 [Program.cs]。

  9. 刪除現有的程式碼。

    您將使用此 C# 主控台專案,在本課程模組期間建立、建置及執行程式碼範例。

  10. 關閉 [終端] 面板。

在程式碼區塊內部建立變數

首先請查看變數在程式碼區塊內初始化的情況。

  1. 請確定您已開啟 Visual Studio Code,並在 [編輯器] 面板中顯示 Program.cs。

    注意

    Program.cs 應該是空的。 如果不是空白,請選取並刪除所有程式碼。

  2. 在 Visual Studio Code 編輯器中輸入下列程式碼:

    bool flag = true;
    if (flag)
    {
        int value = 10;
        Console.WriteLine($"Inside the code block: {value}");
    }
    
  3. 在 Visual Studio Code 的 [檔案] 功能表上,選取 [儲存]。

    在建置或執行程式碼之前,必須先儲存 Program.cs 檔案。

  4. 在 [總管] 面板中,若要在 TestProject 資料夾位置開啟 [終端],請以滑鼠右鍵按一下 [TestProject],然後選取 [在整合式終端機中開啟]。

    [終端] 面板隨即開啟。 終端應該包含命令提示字元,顯示已對 TestProject 資料夾位置開啟終端。

  5. 在終端命令提示字元中,若要執行程式碼,請輸入 dotnet run,然後按 Enter 鍵。

    注意

    如果您看到訊息指出「找不到要執行的專案」,請確定終端命令提示字元會顯示預期的 TestProject 資料夾位置。 例如:C:\Users\someuser\Desktop\csharpprojects\TestProject>

    您應該會看見下列輸出:

    Inside the code block: 10
    

這是預期的輸出。 但是,如果您想要在 if 陳述式的程式碼區塊外部存取變數 value,該怎麼辦?

嘗試存取宣告變數所在程式碼區塊外部的變數

  1. 在 Visual Studio Code 編輯器中,於 if 陳述式程式碼區塊下方建立新的程式碼行。

  2. 在您建立的空白程式碼列上,新增下列程式碼:

    Console.WriteLine($"Outside the code block: {value}");
    
  3. 驗證您更新的程式碼是否如下所示:

    bool flag = true;
    if (flag)
    {
        int value = 10;
        Console.WriteLine($"Inside the code block: {value}");
    }
    Console.WriteLine($"Outside the code block: {value}");
    
  4. 儲存您的程式碼檔案,然後使用 Visual Studio Code 來執行程式碼。

    從終端命令提示字元輸入 dotnet run,以執行您的程式碼。

  5. 請注意,當您嘗試執行應用程式時,將會收到編譯錯誤:

    Program.cs(7,46): error CS0103: The name 'value' does not exist in the current context
    

訊息的 Program.cs(7,46) 部分會告訴您錯誤與 Program.cs 檔案中的第 7 行,資料行 46 相關聯。

產生此錯誤是因為程式碼區塊內宣告的變數只能在該程式碼區塊內存取 (只能查看)。 因為變數無法在宣告變數的程式碼區塊外部存取,無法從程式碼的第 7 行存取 value

在方法程式碼區塊中宣告的變數稱為區域變數。 檢閱討論變數範圍的文章時,您可能會看到使用區域變數一詞。

將變數宣告移至程式碼區塊上方

若要存取程式碼區塊內外的變數,您必須在程式碼區塊之前 (上方) 宣告變數,以便程式碼區塊外部的程式碼可以「查看」變數。

  1. 在 Visual Studio Code 編輯器更新您的程式碼,如下所示:

    bool flag = true;
    int value;
    
    if (flag)
    {
        Console.WriteLine($"Inside the code block: {value}");
    }
    
    value = 10;
    Console.WriteLine($"Outside the code block: {value}");
    
  2. 請花幾分鐘檢閱更新內容。

  3. 請注意,value 現在是在 if 程式碼區塊外部宣告 (但未具初始化)。

  4. 使用 Visual Studio Code 來儲存您的更新,然後執行您的程式碼。

  5. 請注意,您仍會收到編譯錯誤。

    這次嘗試執行應用程式時,您會收到下列編譯錯誤:

    Program.cs(6,49): error CS0165: Use of unassigned local variable 'value'
    

    錯誤與程式碼區塊內的第 6 行相關聯,因為 value 未初始化 (尚未獲指派值)。 如果程式碼行 value = 10; 位於 if 陳述式程式碼區塊上方,則應用程式會正確編譯,且一切正常。 不過,由於 value 尚未初始化,因此無法在程式碼區塊內存取。

    在嘗試存取變數之前,確保先初始化變數,將可解決此問題。

隨著變數宣告的一部分初始化變數

  1. 若要隨著變數宣告的一部分初始化 value,請更新您的程式碼,如下所示:

    bool flag = true;
    int value = 0;
    
    if (flag)
    {
        Console.WriteLine($"Inside the code block: {value}");
    }
    
    value = 10;
    Console.WriteLine($"Outside the code block: {value}");
    

    此程式碼透過初始化 value 作為變數宣告的一部分來解决「未指派的區域變數」編譯錯誤。

  2. 使用 Visual Studio Code 儲存並執行程式碼。

  3. 現在可注意到,當您執行應用程式時會看見下列輸出:

    Inside the code block: 0
    Outside the code block: 10
    

檢查編譯器的程式碼解譯

為避免執行階段錯誤,C# 編譯器會在 Visual Studio Code 編輯器和建置程序期間分析您的程式碼。 不過,編譯器不一定會以您的相同方式來解譯程式碼。

考慮下列兩個看似相同用途的程式碼範例:

// Code sample 1
bool flag = true;
int value;

if (flag)
{
    value = 10;
    Console.WriteLine($"Inside the code block: {value}");
}

Console.WriteLine($"Outside the code block: {value}");
// Code sample 2
int value;

if (true)
{
    value = 10;
    Console.WriteLine($"Inside the code block: {value}");
}

Console.WriteLine($"Outside the code block: {value}");

您可能會覺得這兩個範例應該一律會產生相同的結果,但 C# 編譯器會以不同的方式解譯這兩個程式碼範例。

在第一個程式碼範例中,編譯器會將 flag 解譯為布林值變數,其可以獲指派 truefalse 的值。 編譯器的結論是,如果 flagfalse,在執行第二個 Console.WriteLine() 時將不會初始化 value。 基本上,編譯器會將下列兩個程式碼執行路徑視為可能:

// path when flag = true
int value;
value = 10;
Console.WriteLine($"Inside the code block: {value}");
Console.WriteLine($"Outside the code block: {value}");

// path when flag = false
int value;
Console.WriteLine($"Outside the code block: {value}");

由於編譯器會將第二個路徑視為可能性 (針對程式碼範例 1),因此會在建置程序期間產生錯誤訊息。 此外,Visual Studio Code 中的程式碼編輯器會在 value (程式碼區塊下方) 顯示紅色曲線,以對您提出此問題的警告。

針對第二個程式碼範例,編譯器會得出結論,if 陳述式程式碼區塊的內容一律會執行 (true 一律為 true)。 編譯器不會產生建置錯誤,因為它會將第二個程式碼範例解譯為具有單一執行路徑,如下所示:

int value;
value = 10;
Console.WriteLine($"Inside the code block: {value}");
Console.WriteLine($"Outside the code block: {value}");

概括回顧

以下是程式碼區塊必須記住的數項重點:

  • 在程式碼區塊內宣告變數時,其可見度對該程式碼區塊而言為區域,且無法在程式碼區塊外部存取該變數。
  • 若要確保變數在程式碼區塊內外都可見,您必須在程式碼區塊之前宣告變數 (在程式碼區塊外部和上方)。
  • 在程式碼嘗試存取變數之前,確保變數已初始化 (針對所有可能的程式碼執行路徑)。

檢定您的知識

1.

開發人員會撰寫一些包含 if 陳述式程式碼區塊的程式碼。 這些程式碼會將一個整數變數初始化為程式碼區塊上方 (外部) 的值 5。 這些程式碼會將第二個整數變數初始化為程式碼區塊內第一行的值 6。 如果第一個整數變數的值大於 0,則程式碼區塊的布林運算式會評估為 true。 在程式碼區塊內的第二行,它們將兩個值的總和指派給第一個變數。 在程式碼區塊後的第一行上,他們會撰寫程式碼以顯示第一個整數的值。 執行用來顯示第一個整數的程式碼語句時,其結果為何?