Freigeben über


Tutorial: Schreiben von Code durch das Umsetzen eigener Ideen mithilfe von Anweisungen der obersten Ebene

In dieser Anleitung lernen Sie, wie Sie:

  • Kennenlernen der Regeln für die Verwendung von Anweisungen der obersten Ebene
  • Verwenden von Anweisungen der obersten Ebene zum Untersuchen von Algorithmen
  • Umwandeln von Erkenntnissen in wiederverwendbare Komponenten

Voraussetzungen

Sie müssen Ihren Computer zur Ausführung von .NET 6 oder höher einrichten. Der C# -Compiler steht ab Visual Studio 2022 oder mit .NET SDK zur Verfügung.

In diesem Tutorial wird davon ausgegangen, dass Sie mit C# und .NET vertraut sind (einschließlich Visual Studio oder der .NET-CLI).

Ausprobieren

Mithilfe von Anweisungen der obersten Ebene können Sie den zusätzlichen erforderlichen Schritt vermeiden, indem Sie den Einstiegspunkt Ihres Programms in einer statischen Methode in einer Klasse platzieren. Der typische Startpunkt für eine neue Konsolenanwendung sieht wie der folgende Code aus:

using System;

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

Der vorangegangene Code ist das Ergebnis der Ausführung des dotnet new console Befehls und der Erstellung einer neuen Konsolenanwendung. Diese elf Zeilen enthalten nur eine Zeile ausführbaren Codes. Sie können dieses Programm mit dem neuen Feature für Anweisungen der obersten Ebene vereinfachen. Auf diese Weise können Sie alle Zeilen bis auf zwei in diesem Programm entfernen.

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

Wichtig

Die C#-Vorlagen für .NET 6 verwenden Anweisungen der obersten Ebene. Ihre Anwendung passt möglicherweise nicht zum Code in diesem Artikel, wenn Sie bereits ein Upgrade auf .NET 6 durchgeführt haben. Weitere Informationen finden Sie im Artikel Neue C#-Vorlagen generieren Anweisungen auf oberster Ebene.

Das .NET 6 SDK fügt auch eine Reihe impliziterglobal using Anweisungen für Projekte hinzu, die die folgenden SDKs verwenden:

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

Diese impliziten global using-Anweisungen enthalten die gängigsten Namespaces für den Projekttyp.

Weitere Informationen finden Sie im Artikel zum Thema „Implizite Verwendung von Anweisungen“.

Dieses Feature vereinfacht die Erkundung neuer Ideen. Sie können Anweisungen auf oberster Ebene für Skriptszenarien verwenden oder zum Erkunden nutzen. Sobald Sie die Grundlagen zum Laufen gebracht haben, können Sie mit dem Refactoring des Codes beginnen und Methoden, Klassen oder andere Assemblys für wiederverwendbare Komponenten erstellen, die Sie entwickelt haben. Anweisungen der obersten Ebene ermöglichen das schnelle Testen von Code und bieten eine gute Grundlage für Einsteigertutorials. Außerdem bieten sie eine praktische Möglichkeit für den Übergang von Experimenten mit Code hin zu vollständigen Programmen.

Anweisungen der obersten Ebene werden in der Reihenfolge ausgeführt, in der sie in der Datei aufgeführt sind. Sie können nur in einer Quelldatei in der Anwendung verwendet werden. Der Compiler generiert einen Fehler, wenn Sie die Anweisungen in mehr als einer Datei verwenden.

Entwickeln eines „magischen“ .NET-Programms zum Ausgeben von Antworten

In diesem Tutorial erstellen Sie eine Konsolenanwendung, die eine Frage, die mit „Ja“ oder „Nein“ beantwortet wird, zufällig beantwortet. Sie erstellen die Funktionalität Schritt für Schritt. Sie können sich auf Ihre Aufgabe konzentrieren, anstatt sich mit dem Prozess zum Entwickeln der Struktur eines typischen Programms beschäftigen zu müssen. Sobald Sie mit der Funktionalität zufrieden sind, können Sie die Anwendung nach Bedarf umgestalten.

Es ist ein guter Startpunkt, die Frage wieder in die Konsole zu schreiben. Sie können beginnen, indem Sie den folgenden Code schreiben:

Console.WriteLine(args);

Sie deklarieren keine args-Variable. Im Zusammenhang mit der einzelnen Quelldatei, die die Anweisungen der obersten Ebene enthält, erkennt der Compiler, dass args für die Befehlszeilenargumente steht. Dies sind wie in allen C#-Programmen Argumente vom Typ string[].

Sie können den Code testen, indem Sie den folgenden dotnet run-Befehl ausführen:

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

Die Argumente nach -- in der Befehlszeile werden an das Programm weitergegeben. Sie können den Typ der args-Variablen anzeigen, die in die Konsole gedruckt wird:

System.String[]

Sie müssen die Argumente einzeln benennen und durch ein Leerzeichen trennen, um die Frage in die Konsole zu schreiben. Ersetzen Sie den WriteLine-Aufruf durch den folgenden Code:

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

Wenn Sie das Programm ausführen, wird die Frage nun ordnungsgemäß als Zeichenfolge von Argumenten angezeigt.

Mit einer zufälligen Antwort antworten

Nachdem Sie die Frage wiederholt haben, können Sie den Code hinzufügen, um die zufällige Antwort zu generieren. Fügen Sie zunächst ein Array möglicher Antworten hinzu:

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

Dieses Array umfasst 10 zustimmende, fünf zurückhaltende und fünf verneinende Antworten. Fügen Sie als Nächstes den folgenden Code hinzu, um eine zufällige Antwort aus dem Array zu generieren und anzuzeigen:

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

Sie können die Anwendung noch mal ausführen, um die Ergebnisse anzuzeigen. Es sollte nun etwa die folgende Ausgabe angezeigt werden:

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.

Der Code zum Generieren einer Antwort enthält eine Variablendeklaration in Ihren Anweisungen auf oberster Ebene. Der Compiler schließt diese Deklaration in der vom Compiler generierten Main-Methode ein. Da es sich bei diesen Variablendeklarationen um lokale Variablen handelt, können Sie den static Modifizierer nicht einschließen.

Mit diesem Code werden die Fragen beantwortet, allerdings fügen Sie noch ein weiteres Feature hinzu. Ihre Frage-App soll das Nachdenken vor dem Ausgeben der Antwort simulieren. Sie können das tun, indem Sie etwas ASCII-Animation hinzufügen und während der Arbeit eine Pause einlegen. Fügen Sie den folgenden Code nach der Zeile hinzu, die die Frage wiederholt:

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

Außerdem müssen Sie am Anfang der Quelldatei eine using-Anweisung hinzufügen:

using System.Threading.Tasks;

Die using-Anweisungen müssen sich vor allen anderen Anweisungen in der Datei befinden. Andernfalls tritt ein Compilerfehler auf. Sie können das Programm noch mal ausführen und die Animation anzeigen. Das sorgt für ein besseres Erlebnis. Experimentieren Sie hinsichtlich der Länge der Verzögerung, bis Sie mit dem Ergebnis zufrieden sind.

Der vorangehende Code erstellt eine Reihe von Zeilen, die durch ein Leerzeichen voneinander getrennt sind. Durch das Hinzufügen des Schlüsselworts await wird der Compiler angewiesen, den Programmeinstiegspunkt als Methode zu generieren, die den async-Modifizierer aufweist und die System.Threading.Tasks.Task-Klasse zurückgibt. Dieses Programm gibt keinen Wert zurück, sodass der Programmeinstiegspunkt Task zurückgibt. Wenn das Programm einen ganzzahligen Wert zurückgibt, fügen Sie eine return-Anweisung am Ende der Anweisungen der obersten Ebene hinzu. Diese Rückgabeanweisung würde angeben, welchen ganzzahligen Wert zurückzugeben ist. Wenn die Anweisungen der obersten Ebene einen await-Ausdruck enthalten, wird der Rückgabetyp zu einer System.Threading.Tasks.Task<TResult>-Klasse.

Umgestaltung für die Zukunft

Ihr Programm sollte wie der folgende Code aussehen:

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

Der vorangehende Code ist nützlich. Er funktioniert. Er kann jedoch nicht erneut verwendet werden. Nachdem die Anwendung jetzt funktioniert, ist es an der Zeit, wiederverwendbare Teile zu extrahieren.

Eine Option hierfür ist der Code, der die Animation beim Warten während des Vorgangs anzeigt. Aus diesem Codeausschnitt kann eine Methode werden:

Erstellen Sie hierfür zunächst eine lokale Funktion in der Datei. Ersetzen Sie die aktuelle Animation durch den folgenden Code:

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

Der vorangehende Code erstellt eine lokale Funktion in der Main-Methode. Dieser Code ist immer noch nicht wiederverwendbar. Extrahieren Sie den Code daher in eine Klasse. Erstellen Sie eine neue Datei namens utilities.cs, und fügen Sie den folgenden Code hinzu:

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

Eine Datei mit Anweisungen auf oberster Ebene kann auch Namespaces und Typen am Ende der Datei nach den Anweisungen auf oberster Ebene enthalten. Für dieses Tutorial verwenden Sie die Animationsmethode jedoch in einer separaten Datei, um sie leichter wiederverwenden zu können.

Schließlich können Sie den Animationscode bereinigen, um eine Duplizierung zu entfernen, indem Sie die foreach-Schleife verwenden, um einen Satz von Animationselementen zu durchlaufen, die im animations-Array definiert sind.
Die vollständige ShowConsoleAnimation-Methode nach der Refaktorierung sollte dem folgenden Code ähneln:

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

Nun verfügen Sie über eine komplette Anwendung, und Sie haben die wiederverwendbaren Teile für die spätere Verwendung umgestaltet. Sie können die neue Hilfsprogrammmethode über Ihre Anweisungen der obersten Ebene abrufen, wie in der fertigen Version des Hauptprogramms gezeigt:

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

Im vorherigen Beispiel wird der Aufruf von Utilities.ShowConsoleAnimation hinzugefügt und eine weitere using-Anweisung ergänzt.

Zusammenfassung

Anweisungen der obersten Ebene vereinfachen das Erstellen einfacher Programme, mit denen neue Algorithmen untersucht werden können. Sie können mit Algorithmen experimentieren, indem Sie verschiedene Codeausschnitte ausprobieren. Nachdem Sie gelernt haben, was funktioniert, können Sie den Code so umgestalten, dass er leichter verwaltet werden kann.

Anweisungen der obersten Ebene vereinfachen Programme, die auf Konsolen-Apps basieren. Hierzu gehören Azure-Funktionen, GitHub-Aktionen und andere kleine Hilfsprogramme. Weitere Informationen finden Sie unter Anweisungen auf oberster Ebene (C#-Programmierleitfaden).