教學課程:探索使用最上層語句在學習時建置程序代碼的想法

在本教學課程中,您將了解如何:

  • 瞭解管理您使用最上層語句的規則。
  • 使用最上層語句來探索演算法。
  • 將探索重構為可重複使用的元件。

必要條件

您必須設定您的電腦以執行 .NET 6,其中包括 C# 10 編譯程式。 C# 10 編譯程式可從 Visual Studio 2022.NET 6 SDK 開始使用。

本教學課程假設您已熟悉 C# 和 .NET,包括 Visual Studio 或 .NET CLI。

開始探索

最上層語句可讓您避免將程序進入點放在類別中的靜態方法所需的額外儀式。 新主控台應用程式的一般起點看起來像下列程式代碼:

using System;

namespace Application
{
    class Program
    {
        static void Main(string[] args)
        {
            Console.WriteLine("Hello World!");
        }
    }
}

上述程式代碼是執行 dotnet new console 命令並建立新控制台應用程式的結果。 這 11 行只包含一行可執行的程式代碼。 您可以使用新的最上層語句功能來簡化該程式。 這可讓您移除此程式中所有行,但兩行:

// See https://aka.ms/new-console-template for more information
Console.WriteLine("Hello, World!");

重要

.NET 6 的 C# 範本使用 最上層語句。 如果您已經升級至 .NET 6,您的應用程式可能不符合本文中的程序代碼。 如需詳細資訊,請參閱新 C# 範本會產生最上層陳述式一文

.NET 6 SDK 也會為使用下列 SDK 的專案新增一組 隱含global using 指示詞:

  • Microsoft.NET.Sdk
  • Microsoft.NET.Sdk.Web
  • Microsoft.NET.Sdk.Worker

這些隱含 global using 指示詞包含該專案類型最常見的命名空間。

如需詳細資訊,請參閱隱含using指示詞一文

此功能可簡化開始探索新想法所需的專案。 您可以使用最上層語句來編寫腳本案例,或探索。 一旦基本概念正常運作,您就可以開始重構程序代碼,並針對您所建置的可重複使用元件建立方法、類別或其他元件。 最上層語句可啟用快速實驗和初學者教學課程。 它們也提供從實驗到完整程式的完整路徑。

最上層語句的執行順序為檔案中出現的順序。 最上層語句只能在應用程式中的一個原始程序檔中使用。 如果您在多個檔案中使用它們,編譯程式會產生錯誤。

建置魔術 .NET 回應計算機

在本教學課程中,讓我們建置控制台應用程式,以隨機答案回答「是」或「否」問題。 您將逐步建置功能。 您可以專注於工作,而不是一般程序結構所需的儀式。 然後,一旦您對功能感到滿意,您就可以在看到適合時重構應用程式。

一個很好的起點是將問題寫回控制台。 您可以從撰寫下列程式代碼開始:

Console.WriteLine(args);

您不會宣告 args 變數。 針對包含最上層語句的單一原始程式檔,編譯程式會辨識 args 為表示命令行自變數。 args 的類型是 , string[]如同所有 C# 程序一樣。

您可以執行下列 dotnet run 命令來測試程式代碼:

dotnet run -- Should I use top level statements in all my programs?

命令行上的 之後 -- 的 自變數會傳遞至程式。 您可以看到變數的類型 args ,因為這是列印到主控台的內容:

System.String[]

若要將問題寫入主控台,您必須列舉自變數,並使用空格加以分隔。 以 WriteLine 下列程式代碼取代 呼叫:

Console.WriteLine();
foreach(var s in args)
{
    Console.Write(s);
    Console.Write(' ');
}
Console.WriteLine();

現在,當您執行程式時,它會正確地將問題顯示為自變數字串。

以隨機答案回應

響應問題之後,您可以新增程式代碼來產生隨機答案。 從新增可能答案的陣列開始:

string[] answers =
[
    "It is certain.",       "Reply hazy, try again.",     "Don’t count on it.",
    "It is decidedly so.",  "Ask again later.",           "My reply is no.",
    "Without a doubt.",     "Better not tell you now.",   "My sources say no.",
    "Yes – definitely.",    "Cannot predict now.",        "Outlook not so good.",
    "You may rely on it.",  "Concentrate and ask again.", "Very doubtful.",
    "As I see it, yes.",
    "Most likely.",
    "Outlook good.",
    "Yes.",
    "Signs point to yes.",
];

這個陣列有十個肯定答案,五個是非認可,五個是負數。 接下來,新增下列程式代碼,以從數位列程式產生並顯示隨機答案:

var index = new Random().Next(answers.Length - 1);
Console.WriteLine(answers[index]);

您可以再次執行應用程式以查看結果。 您應該會看到如下的輸出:

dotnet run -- Should I use top level statements in all my programs?

Should I use top level statements in all my programs?
Better not tell you now.

此程式代碼會回答問題,但讓我們再新增一項功能。 您想要您的問題應用程式模擬對答案的思考。 您可以藉由新增一些 ASCII 動畫,並在運作時暫停來執行此動作。 在回應問題的行後面新增下列程式代碼:

for (int i = 0; i < 20; i++)
{
    Console.Write("| -");
    await Task.Delay(50);
    Console.Write("\b\b\b");
    Console.Write("/ \\");
    await Task.Delay(50);
    Console.Write("\b\b\b");
    Console.Write("- |");
    await Task.Delay(50);
    Console.Write("\b\b\b");
    Console.Write("\\ /");
    await Task.Delay(50);
    Console.Write("\b\b\b");
}
Console.WriteLine();

您也必須將 語句新增 using 至原始程式檔頂端:

using System.Threading.Tasks;

語句 using 必須位於 檔案中任何其他語句之前。 否則,這是編譯程序錯誤。 您可以再次執行程式並查看動畫。 這使得體驗更好。 實驗延遲的長度,以符合您的口味。

上述程式代碼會建立一組以空格分隔的旋轉線。 await新增 關鍵詞會指示編譯程式產生程式進入點做為具有 async 修飾詞的方法,並傳System.Threading.Tasks.Task回 。 此程式不會傳回值,因此程式進入點會傳 Task回 。 如果您的程式傳回整數值,您會將 return 語句新增至最上層語句的結尾。 該 return 語句會指定要傳回的整數值。 如果您的最上層語句包含 await 表示式,則傳回型別會 System.Threading.Tasks.Task<TResult>變成 。

重構未來

您的程式看起來應該像下列程式代碼:

Console.WriteLine();
foreach(var s in args)
{
    Console.Write(s);
    Console.Write(' ');
}
Console.WriteLine();

for (int i = 0; i < 20; i++)
{
    Console.Write("| -");
    await Task.Delay(50);
    Console.Write("\b\b\b");
    Console.Write("/ \\");
    await Task.Delay(50);
    Console.Write("\b\b\b");
    Console.Write("- |");
    await Task.Delay(50);
    Console.Write("\b\b\b");
    Console.Write("\\ /");
    await Task.Delay(50);
    Console.Write("\b\b\b");
}
Console.WriteLine();

string[] answers =
[
    "It is certain.",       "Reply hazy, try again.",     "Don't count on it.",
    "It is decidedly so.",  "Ask again later.",           "My reply is no.",
    "Without a doubt.",     "Better not tell you now.",   "My sources say no.",
    "Yes – definitely.",    "Cannot predict now.",        "Outlook not so good.",
    "You may rely on it.",  "Concentrate and ask again.", "Very doubtful.",
    "As I see it, yes.",
    "Most likely.",
    "Outlook good.",
    "Yes.",
    "Signs point to yes.",
];

var index = new Random().Next(answers.Length - 1);
Console.WriteLine(answers[index]);

上述程序代碼很合理。 這麼做確實有成效。 但它不能重複使用。 現在您已讓應用程式運作,現在可以提取可重複使用的元件。

其中一個候選項目是顯示等候動畫的程序代碼。 該代碼段可以成為方法:

您可以從在檔案中建立本機函式開始。 以下欄程序代碼取代目前的動畫:

await ShowConsoleAnimation();

static async Task ShowConsoleAnimation()
{
    for (int i = 0; i < 20; i++)
    {
        Console.Write("| -");
        await Task.Delay(50);
        Console.Write("\b\b\b");
        Console.Write("/ \\");
        await Task.Delay(50);
        Console.Write("\b\b\b");
        Console.Write("- |");
        await Task.Delay(50);
        Console.Write("\b\b\b");
        Console.Write("\\ /");
        await Task.Delay(50);
        Console.Write("\b\b\b");
    }
    Console.WriteLine();
}

上述程式代碼會在您的main方法內建立本機函式。 這仍然無法重複使用。 因此,將該程式代碼擷取至 類別。 建立名為 utilities.cs 的新檔案,並新增下列程式代碼:

namespace MyNamespace
{
    public static class Utilities
    {
        public static async Task ShowConsoleAnimation()
        {
            for (int i = 0; i < 20; i++)
            {
                Console.Write("| -");
                await Task.Delay(50);
                Console.Write("\b\b\b");
                Console.Write("/ \\");
                await Task.Delay(50);
                Console.Write("\b\b\b");
                Console.Write("- |");
                await Task.Delay(50);
                Console.Write("\b\b\b");
                Console.Write("\\ /");
                await Task.Delay(50);
                Console.Write("\b\b\b");
            }
            Console.WriteLine();
        }
    }
}

在最上層語句之後,具有最上層語句的檔案也可以包含檔案結尾的命名空間和類型。 但在本教學課程中,您會將動畫方法放在個別的檔案中,使其更容易重複使用。

最後,您可以清除動畫程式代碼以移除一些重複專案:

foreach (string s in animations)
{
    Console.Write(s);
    await Task.Delay(50);
    Console.Write("\b\b\b");
}

現在您已擁有完整的應用程式,且已重構可重複使用的元件以供日後使用。 您可以從最上層語句呼叫新的公用程式方法,如主要程式的完成版本所示:

using MyNamespace;

Console.WriteLine();
foreach(var s in args)
{
    Console.Write(s);
    Console.Write(' ');
}
Console.WriteLine();

await Utilities.ShowConsoleAnimation();

string[] answers =
[
    "It is certain.",       "Reply hazy, try again.",     "Don’t count on it.",
    "It is decidedly so.",  "Ask again later.",           "My reply is no.",
    "Without a doubt.",     "Better not tell you now.",   "My sources say no.",
    "Yes – definitely.",    "Cannot predict now.",        "Outlook not so good.",
    "You may rely on it.",  "Concentrate and ask again.", "Very doubtful.",
    "As I see it, yes.",
    "Most likely.",
    "Outlook good.",
    "Yes.",
    "Signs point to yes.",
];

var index = new Random().Next(answers.Length - 1);
Console.WriteLine(answers[index]);

上述範例會將呼叫新增至 Utilities.ShowConsoleAnimation,並新增其他 using 語句。

摘要

最上層語句可讓您更輕鬆地建立簡單的程式,以用來探索新的演算法。 您可以嘗試不同的代碼段來實驗演算法。 了解運作方式后,您可以重構程序代碼以更容易維護。

最上層語句會簡化以控制台應用程式為基礎的程式。 其中包括 Azure 函式、GitHub 動作和其他小型公用程式。 如需詳細資訊,請參閱最上層語句(C# 程式設計手冊)。