Tutorial: Schreiben von Code durch das Umsetzen eigener Ideen mithilfe von Anweisungen der obersten EbeneTutorial: Explore ideas using top-level statements to build code as you learn

In diesem Tutorial lernen Sie Folgendes:In this tutorial, you'll learn how to:

  • Kennenlernen der Regeln für die Verwendung von Anweisungen der obersten EbeneLearn the rules governing your use of top-level statements.
  • Verwenden von Anweisungen der obersten Ebene zum Untersuchen von AlgorithmenUse top-level statements to explore algorithms.
  • Umwandeln von Erkenntnissen in wiederverwendbare KomponentenRefactor explorations into reusable components.

VoraussetzungenPrerequisites

Sie müssen Ihren Computer zur Ausführung von .NET 5 einrichten, einschließlich des C# 9-Compilers.You'll need to set up your machine to run .NET 5, which includes the C# 9 compiler. Der C# 9-Compiler steht ab Visual Studio 2019 Version 16.9 Preview 1 oder .NET 5.0 SDK zur Verfügung.The C# 9 compiler is available starting with Visual Studio 2019 version 16.9 preview 1 or .NET 5.0 SDK.

In diesem Tutorial wird vorausgesetzt, dass Sie C# und .NET, einschließlich Visual Studio oder die .NET Core-CLI kennen.This tutorial assumes you're familiar with C# and .NET, including either Visual Studio or the .NET Core CLI.

AusprobierenStart exploring

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.Top-level statements enable you to avoid the extra ceremony required by placing your program's entry point in a static method in a class. Der typische Startpunkt für eine neue Konsolenanwendung sieht wie der folgende Code aus:The typical starting point for a new console application looks like the following code:

using System;

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

Der vorangehende Code ist das Ergebnis der Ausführung des dotnet new console-Befehls und der Erstellung einer neuen Konsolenanwendung.The preceding code is the result of running the dotnet new console command and creating a new console application. Diese elf Zeilen enthalten nur eine Zeile ausführbaren Codes.Those 11 lines contain only one line of executable code. Sie können dieses Programm mit dem neuen Feature für Anweisungen der obersten Ebene vereinfachen.You can simplify that program with the new top-level statements feature. Dadurch können Sie in diesem Programm bis auf zwei Zeilen alle anderen Zeilen entfernen.That enables you to remove all but two of the lines in this program:

using System;

Console.WriteLine("Hello World!");

Durch diese Aktion wird das Umsetzen neuer Ideen vereinfacht.This action simplifies what's needed to begin exploring new ideas. Sie können Anweisungen der obersten Ebene für Skripterstellungsszenarios oder zum Durchsuchen verwenden.You can use top-level statements for scripting scenarios, or to explore. Sobald Sie die Grundlagen beherrschen, können Sie mit dem Umgestalten des Codes beginnen und Methoden, Klassen oder andere Assemblys für von Ihnen entwickelte wiederverwendbare Komponenten erstellen.Once you've got the basics working, you can start refactoring the code and create methods, classes, or other assemblies for reusable components you've built. Anweisungen der obersten Ebene ermöglichen das schnelle Testen von Code und bieten eine gute Grundlage für Einsteigertutorials.Top-level statements do enable quick experimentation and beginner tutorials. Außerdem bieten sie eine praktische Möglichkeit für den Übergang von Experimenten mit Code hin zu vollständigen Programmen.They also provide a smooth path from experimentation to full programs.

Anweisungen der obersten Ebene werden in der Reihenfolge ausgeführt, in der sie in der Datei aufgeführt sind.Top-level statements are executed in the order they appear in the file. Sie können nur in einer Quelldatei in der Anwendung verwendet werden.Top-level statements can only be used in one source file in your application. Der Compiler generiert einen Fehler, wenn Sie die Anweisungen in mehr als einer Datei verwenden.The compiler generates an error if you use them in more than one file.

Entwickeln eines „magischen“ .NET-Programms zum Ausgeben von AntwortenBuild a magic .NET answer machine

In diesem Tutorial erstellen Sie eine Konsolenanwendung, die eine Frage, die mit „Ja“ oder „Nein“ beantwortet wird, zufällig beantwortet.For this tutorial, let's build a console application that answers a "yes" or "no" question with a random answer. Sie erstellen die Funktionalität Schritt für Schritt.You'll build out the functionality step by step. 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.You can focus on your task rather than ceremony needed for the structure of a typical program. Sobald Sie mit der Funktionalität zufrieden sind, können Sie die Anwendung nach Bedarf umgestalten.Then, once you're happy with the functionality, you can refactor the application as you see fit.

Es ist ein guter Startpunkt, die Frage wieder in die Konsole zu schreiben.A good starting point is to write the question back to the console. Sie können beginnen, indem Sie den folgenden Code schreiben:You can start by writing the following code:

using System;

Console.WriteLine(args);

Sie deklarieren keine args-Variable.You don't declare an 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.For the single source file that contains your top-level statements, the compiler recognizes args to mean the command-line arguments. Dies sind wie in allen C#-Programmen Argumente vom Typ string[].The type of args is a string[], as in all C# programs.

Sie können den Code testen, indem Sie den folgenden dotnet run-Befehl ausführen:You can test your code by running the following dotnet run command:

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

Die Argumente nach -- in der Befehlszeile werden an das Programm weitergegeben.The arguments after the -- on the command line are passed to the program. Sie können den Typ der args-Variable sehen, da diese Information in der Konsole angezeigt wird:You can see the type of the args variable, because that's what's printed to the console:

System.String[]

Sie müssen die Argumente einzeln benennen und durch ein Leerzeichen trennen, um die Frage in die Konsole zu schreiben.To write the question to the console, you'll need to enumerate the arguments and separate them with a space. Ersetzen Sie den WriteLine-Aufruf durch den folgenden Code:Replace the WriteLine call with the following 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.Now, when you run the program, it will correctly display the question as a string of arguments.

Antworten mit einer zufälligen AntwortRespond with a random answer

Nachdem Sie die Frage wiederholt haben, können Sie den Code hinzufügen, um die zufällige Antwort zu generieren.After echoing the question, you can add the code to generate the random answer. Fügen Sie zunächst ein Array möglicher Antworten hinzu:Start by adding an array of possible answers:

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 zwölf positive, sechs zurückhaltende und sechs negative Antworten.This array has 12 answers that are affirmative, six that are non-committal, and six that are negative. Fügen Sie als Nächstes den folgenden Code hinzu, um eine zufällige Antwort aus dem Array zu generieren und anzuzeigen:Next, add the following code to generate and display a random answer from the array:

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.You can run the application again to see the results. Es sollte nun etwa die folgende Ausgabe angezeigt werden:You should see something like the following output:

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.

Mit diesem Code werden die Fragen beantwortet, allerdings fügen Sie noch ein weiteres Feature hinzu.This code answers the questions, but let's add one more feature. Ihre Frage-App soll das Nachdenken vor dem Ausgeben der Antwort simulieren.You'd like your question app to simulate thinking about the answer. Dies erreichen Sie, indem Sie eine ASCII-Animation (American Standard Code for Information Interchange) hinzufügen und den restlichen Vorgang während der Bearbeitung anhalten.You can do that by adding a bit of ASCII animation, and pausing while working. Fügen Sie den folgenden Code nach der Zeile hinzu, die die Frage wiederholt:Add the following code after the line that echoes the question:

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:You'll also need to add a using statement to the top of the source file:

using System.Threading.Tasks;

Die using-Anweisungen müssen sich vor allen anderen Anweisungen in der Datei befinden.The using statements must be before any other statements in the file. Andernfalls tritt ein Compilerfehler auf.Otherwise, it's a compiler error. Sie können das Programm noch mal ausführen und die Animation anzeigen.You can run the program again and see the animation. Dies ermöglicht eine bessere Nutzung des Programms.That makes a better experience. Experimentieren Sie hinsichtlich der Länge der Verzögerung, bis Sie mit dem Ergebnis zufrieden sind.Experiment with the length of the delay to match your taste.

Der vorangehende Code erstellt eine Reihe von Zeilen, die durch ein Leerzeichen voneinander getrennt sind.The preceding code creates a set of spinning lines separated by a space. 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.Adding the await keyword instructs the compiler to generate the program entry point as a method that has the async modifier, and returns a System.Threading.Tasks.Task. Dieses Programm gibt keinen Wert zurück, sodass der Programmeinstiegspunkt Task zurückgibt.This program does not return a value, so the program entry point returns a Task. Wenn das Programm einen ganzzahligen Wert zurückgibt, fügen Sie eine return-Anweisung am Ende der Anweisungen der obersten Ebene hinzu.If your program returns an integer value, you would add a return statement to the end of your top-level statements. Diese return-Anweisung gibt den ganzzahligen Wert an, der zurückgegeben wird.That return statement would specify the integer value to return. Wenn die Anweisungen der obersten Ebene einen await-Ausdruck enthalten, wird der Rückgabetyp zu einer System.Threading.Tasks.Task<TResult>-Klasse.If your top-level statements include an await expression, the return type becomes System.Threading.Tasks.Task<TResult>.

Umgestaltung für die ZukunftRefactoring for the future

Ihr Programm sollte wie der folgende Code aussehen:Your program should look like the following code:

using System;
using System.Threading.Tasks;

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.The preceding code is reasonable. Er funktioniert.It works. Er kann jedoch nicht erneut verwendet werden.But it isn't reusable. Nachdem die Anwendung jetzt funktioniert, ist es an der Zeit, wiederverwendbare Teile zu extrahieren.Now that you have the application working, it's time to pull out reusable parts.

Eine Option hierfür ist der Code, der die Animation beim Warten während des Vorgangs anzeigt.One candidate is the code that displays the waiting animation. Aus diesem Codeausschnitt kann eine Methode werden:That snippet can become a method:

Erstellen Sie hierfür zunächst eine lokale Funktion in der Datei.You can start by creating a local function in your file. Ersetzen Sie die aktuelle Animation durch den folgenden Code:Replace the current animation with the following 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.The preceding code creates a local function inside your main method. Diese ist immer noch nicht wiederverwendbar.That's still not reusable. Extrahieren Sie den Code daher in eine Klasse.So, extract that code into a class. Erstellen Sie eine neue Datei namens utilities.cs , und fügen Sie den folgenden Code hinzu:Create a new file named utilities.cs and add the following code:

using System;
using System.Threading.Tasks;

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

Anweisungen der obersten Ebene können nur in einer Datei enthalten sein, und diese Datei darf keine Namespaces oder Typen enthalten.Top-level statements can only be in one file, and that file cannot contain namespaces or types.

Zum Schluss können Sie den Animationscode bereinigen, um Duplizierungen zu entfernen:Finally, you can clean the animation code to remove some duplication:

foreach (string s in new[] { "| -", "/ \\", "- |", "\\ /", })
{
    Console.Write(s);
    await Task.Delay(50);
    Console.Write("\b\b\b");
}

Nun verfügen Sie über eine komplette Anwendung, und Sie haben die wiederverwendbaren Teile für die spätere Verwendung umgestaltet.Now you have a complete application, and you've refactored the reusable parts for later use.

ZusammenfassungSummary

Anweisungen der obersten Ebene vereinfachen das Erstellen einfacher Programme, mit denen neue Algorithmen untersucht werden können.Top-level statements make it easier to create simple programs for use to explore new algorithms. Sie können mit Algorithmen experimentieren, indem Sie verschiedene Codeausschnitte ausprobieren.You can experiment with algorithms by trying different snippets of code. Nachdem Sie gelernt haben, was funktioniert, können Sie den Code so umgestalten, dass er leichter verwaltet werden kann.Once you've learned what works, you can refactor the code to be more maintainable.

Anweisungen der obersten Ebene vereinfachen Programme, die auf Konsolenanwendungen basieren.Top-level statements simplify programs that are based on console applications. Hierzu gehören Azure-Funktionen, GitHub-Aktionen und andere kleine Hilfsprogramme.These include Azure functions, GitHub actions, and other small utilities.