Dela via


Självstudie: Utforska idéer med hjälp av toppnivåinstruktioner för att skapa kod när du lär dig

I den här handledningen lär du dig hur:

  • Lär dig reglerna som styr din användning av toppnivåuttryck.
  • Använd toppnivåinstruktioner för att utforska algoritmer.
  • Omstrukturera utforskningar till återanvändbara komponenter.

Förutsättningar

Du måste konfigurera datorn för att köra .NET 6 eller senare. C#-kompilatorn är tillgänglig från och med Visual Studio 2022 eller .NET SDK.

Den här handledningen förutsätter att du är bekant med C# och .NET, inklusive Visual Studio eller .NET CLI.

Börja utforska

Med toppnivåinstruktioner kan du undvika den extra ceremoni som krävs genom att placera programmets startpunkt i en statisk metod i en klass. Den typiska startpunkten för ett nytt konsolprogram ser ut som följande kod:

using System;

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

Föregående kod är resultatet av att köra kommandot dotnet new console och skapa ett nytt konsolprogram. Dessa 11 rader innehåller bara en rad körbar kod. Du kan förenkla programmet med den nya funktionen för toppnivåuttalanden. Det gör att du kan ta bort alla rader utom två i det här programmet:

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

Viktig

C#-mallarna för .NET 6 använder toppnivåinstruktioner. Programmet kanske inte matchar koden i den här artikeln om du redan har uppgraderat till .NET 6. Mer information finns i artikeln om Nya C#-mallar genererar toppnivåinstruktioner

.NET 6 SDK lägger också till en uppsättning implicitaglobal using-direktiv för projekt som använder följande SDK:er:

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

Dessa implicita global using direktiv innehåller de vanligaste namnrymderna för projekttypen.

Mer information finns i artikeln om Implicit med hjälp av direktiv

Den här funktionen förenklar din utforskning av nya idéer. Du kan använda instruktioner på den översta nivån för skriptscenarier eller utforska dem. När du har fått grunderna att fungera kan du börja omstrukturera koden och skapa metoder, klasser eller andra sammansättningar för återanvändbara komponenter som du har skapat. Uttalanden på toppnivå möjliggör snabba experiment och nybörjarhandledningar. De ger också en smidig väg från experimentering till fullständiga program.

Toppnivåinstruktioner körs i den ordning de visas i filen. Toppnivåinstruktioner kan bara användas i en källfil i ditt program. Kompilatorn genererar ett fel om du använder dem i mer än en fil.

Skapa en magisk .NET-svarsdator

I den här självstudien ska vi skapa ett konsolprogram som svarar på en "ja" eller "nej"-fråga med ett slumpmässigt svar. Du skapar funktionerna steg för steg. Du kan fokusera på din uppgift snarare än ceremoni som behövs för strukturen för ett typiskt program. När du är nöjd med funktionerna kan du sedan omstrukturera programmet så som du vill.

En bra utgångspunkt är att skriva tillbaka frågan till konsolen. Du kan börja med att skriva följande kod:

Console.WriteLine(args);

Du deklarerar inte en args variabel. För den enda källfil som innehåller dina toppnivåinstruktioner identifierar kompilatorn args att betyda kommandoradsargumenten. Typen av args är en string[], som i alla C#-program.

Du kan testa koden genom att köra följande dotnet run kommando:

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

Argumenten efter -- på kommandoraden skickas till programmet. Du kan se vilken typ av args variabel som skrivs ut till konsolen:

System.String[]

Om du vill skriva frågan till konsolen måste du räkna upp argumenten och separera dem med ett blanksteg. Ersätt WriteLine-anropet med följande kod:

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

När du kör programmet visas frågan som en sträng med argument.

Svara med ett slumpmässigt svar

När du har upprepat frågan kan du lägga till koden för att generera det slumpmässiga svaret. Börja med att lägga till en matris med möjliga svar:

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.",
];

Den här matrisen har 10 svar som är jakande, fem som inte är bindande och fem som är negativa. Lägg sedan till följande kod för att generera och visa ett slumpmässigt svar från matrisen:

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

Du kan köra programmet igen för att se resultatet. Du bör se något som liknar följande utdata:

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.

Koden för att generera ett svar innehåller en variabeldeklaration i dina toppnivåinstruktioner. Kompilatorn inkluderar denna deklaration i den kompilatorgenererade Main-metoden. Eftersom dessa variabeldeklarationer är lokala variabler kan du inte ta med static-modifieraren.

Den här koden besvarar frågorna, men vi lägger till ytterligare en funktion. Du vill att din frågeapp ska simulera att du tänker på svaret. Du kan göra det genom att lägga till lite ASCII-animering och pausa när du arbetar. Lägg till följande kod efter raden som ekar frågan:

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();

Du måste också lägga till ett using-direktiv överst i källfilen:

using System.Threading.Tasks;

De using direktiven måste finnas före andra instruktioner i filen. Annars är det ett kompilatorfel. Du kan köra programmet igen och se animeringen. Det gör en bättre upplevelse. Experimentera med längden på fördröjningen för att matcha din smak.

Föregående kod skapar en uppsättning snurrande rader avgränsade med ett blanksteg. Genom att lägga till nyckelordet await instrueras kompilatorn att generera programmets startpunkt som en metod som har async-modifieraren och returnerar en System.Threading.Tasks.Task. Det här programmet returnerar inte något värde, så programmets startpunkt returnerar en Task. Om ditt program returnerar ett heltalsvärde lägger du till en retursats i slutet av dina top-level-uttalanden. Den returnerade instruktionen skulle ange heltalsvärdet som ska returneras. Om dina toppnivåinstruktioner innehåller ett await uttryck blir returtypen System.Threading.Tasks.Task<TResult>.

Refaktorisering för framtiden

Programmet bör se ut som följande kod:

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]);

Föregående kod är rimlig. Det fungerar. Men det går inte att återanvända. Nu när programmet fungerar är det dags att hämta återanvändbara delar.

En kandidat är koden som visar den väntande animeringen. Det kodfragmentet kan bli en metod:

Du kan börja med att skapa en lokal funktion i filen. Ersätt den aktuella animeringen med följande kod:

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();
}

Föregående kod skapar en lokal funktion i huvudmetoden. Koden kan fortfarande inte återanvändas. Extrahera koden till en klass. Skapa en ny fil med namnet utilities.cs och lägg till följande kod:

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();
        }
    }
}

En fil som har toppnivåinstruktioner kan också innehålla namnområden och typer i slutet av filen, efter de översta instruktionerna. Men i den här självstudien placerar du animeringsmetoden i en separat fil för att göra den enklare att återanvända.

Slutligen kan du rensa animeringskoden för att ta bort viss duplicering genom att använda foreach loop för att iterera genom uppsättning animeringselement som definierats i animations matris.
Den fullständiga ShowConsoleAnimation-metoden efter refaktorn bör se ut ungefär så här:

public static async Task ShowConsoleAnimation()
{
    string[] animations = ["| -", "/ \\", "- |", "\\ /"];
    for (int i = 0; i < 20; i++)
    {
        foreach (string s in animations)
        {
            Console.Write(s);
            await Task.Delay(50);
            Console.Write("\b\b\b");
        }
    }
    Console.WriteLine();
}

Nu har du ett komplett program och omstrukturerat återanvändbara delar för senare användning. Du kan anropa den nya verktygsmetoden från dina toppnivåinstruktioner, som du ser i den färdiga versionen av huvudprogrammet:

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]);

Föregående exempel lägger till anropet till Utilities.ShowConsoleAnimationoch lägger till ett annat using-direktiv.

Sammanfattning

Toppnivåinstruktioner gör det enklare att skapa enkla program som kan användas för att utforska nya algoritmer. Du kan experimentera med algoritmer genom att prova olika kodfragment. När du har lärt dig vad som fungerar kan du omstrukturera koden så att den blir mer underhållsbar.

Toppnivåinstruktioner förenklar program som baseras på konsolappar. Dessa appar omfattar Azure-funktioner, GitHub-åtgärder och andra små verktyg. Mer information finns i instruktioner på toppnivå (C#-programmeringsguide).