Hinweis
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, sich anzumelden oder das Verzeichnis zu wechseln.
Für den Zugriff auf diese Seite ist eine Autorisierung erforderlich. Sie können versuchen, das Verzeichnis zu wechseln.
Dateibasierte Apps sind Programme , die in einer einzelnen *.cs Datei enthalten sind, die ohne eine entsprechende Projektdatei (*.csproj) erstellt und ausgeführt werden. Dateibasierte Apps eignen sich ideal zum Erlernen von C#, da sie weniger Komplexität haben: Das gesamte Programm wird in einer einzelnen Datei gespeichert. Dateibasierte Apps eignen sich auch zum Erstellen von Befehlszeilenprogrammen. Auf Unix-Plattformen können dateibasierte Apps mit #! (Shebang)- Direktiven ausgeführt werden.
In diesem Tutorial führen Sie Folgendes durch:
- Erstellen Sie ein dateibasiertes Programm.
- Unterstützung für Unix-Shebang (
#!) hinzufügen. - Befehlszeilenargumente lesen.
- Behandeln von Standardeingaben.
- Schreiben der ASCII-Grafikausgabe.
- Verarbeiten von Befehlszeilenargumenten.
- Verwenden Sie analysierte Befehlszeilenergebnisse.
- Testen Sie die endgültige Anwendung.
Sie erstellen ein dateibasiertes Programm, das Text als ASCII-Grafik schreibt. Die App ist in einer einzelnen Datei enthalten, verwendet NuGet-Pakete, die einige der Kernfeatures implementieren.
Voraussetzungen
- The .NET 10 SDK. Laden Sie es von der .NET-Downloadwebsite herunter.
- Visual Studio Code. Laden Sie es von der Visual Studio Code-Startseite herunter.
- (Optional) Die C#DevKit-Erweiterung für Visual Studio Code. Laden Sie es aus dem Visual Studio Code Marketplace herunter.
Erstellen eines dateibasierten Programms
Öffnen Sie Visual Studio Code, und erstellen Sie eine neue Datei mit dem Namen
AsciiArt.cs. Geben Sie den folgenden Text ein:Console.WriteLine("Hello, world!");Speichern Sie die Datei. Öffnen Sie dann das integrierte Terminal in Visual Studio Code, und geben Sie Folgendes ein:
dotnet run AsciiArt.cs
Wenn Sie dieses Programm zum ersten Mal ausführen, erstellt der dotnet Host die ausführbare Datei aus Ihrer Quelldatei, speichert Buildartefakte in einem temporären Ordner und führt dann die erstellte ausführbare Datei aus. Sie können diese Erfahrung überprüfen, indem Sie sie erneut eingeben dotnet run AsciiArt.cs . Dieses Mal bestimmt der dotnet Host, dass die ausführbare Datei aktuell ist, und führt die ausführbare Datei aus, ohne sie erneut zu erstellen. Es wird keine Buildausgabe angezeigt.
Die vorstehenden Schritte veranschaulichen, dass dateibasierte Apps keine Skriptdateien sind. Es handelt sich um C#-Quelldateien, die mithilfe einer generierten Projektdatei in einem temporären Ordner erstellt werden. Eine der Ausgabezeilen, die angezeigt werden, wenn Sie das Programm erstellt haben, sollte etwa wie folgt aussehen (unter Windows):
AsciiArt succeeded (7.3s) → AppData\Local\Temp\dotnet\runfile\AsciiArt-85c58ae0cd68371711f06f297fa0d7891d0de82afde04d8c64d5f910ddc04ddc\bin\debug\AsciiArt.dll
Auf Unix-Plattformen ähnelt der Ausgabeordner folgendem:
AsciiArt succeeded (7.3s) → Library/Application Support/dotnet/runfile/AsciiArt-85c58ae0cd68371711f06f297fa0d7891d0de82afde04d8c64d5f910ddc04ddc/bin/debug/AsciiArt.dll
Diese Ausgabe teilt Ihnen mit, wo die temporären Dateien und Buildausgaben platziert werden. Während dieses Lernprogramms aktualisiert der dotnet Host die ausführbare Datei, wenn Sie die Quelldatei bearbeiten, bevor sie ausgeführt wird.
Dateibasierte Apps sind normale C#-Programme. Die einzige Einschränkung besteht darin, dass sie in einer Quelldatei geschrieben werden müssen. Sie können Anweisungen der obersten Ebene oder eine klassische Main Methode als Einstiegspunkt verwenden. Sie können alle Typen deklarieren: Klassen, Schnittstellen und Strukturen. Sie können die Algorithmen in einem dateibasierten Programm so strukturiert wie in jedem beliebigen C#-Programm. Sie können sogar mehrere Namespaces deklarieren, um Ihren Code zu organisieren. Wenn Sie feststellen, dass ein dateibasiertes Programm für eine einzelne Datei zu groß wird, können Sie es in ein projektbasiertes Programm konvertieren und die Quelle in mehrere Dateien aufteilen. Dateibasierte Apps sind ein hervorragendes Prototyptool. Sie können mit minimalem Aufwand experimentieren, um Konzepte zu beweisen und Algorithmen zu erstellen.
Unix shebang (#!) Unterstützung
Hinweis
Die Unterstützung von #! Direktiven gilt nur für Unix-Plattformen. Es gibt keine ähnliche Direktive für Windows, um ein C#-Programm direkt auszuführen. Unter Windows müssen Sie die Befehlszeile verwenden dotnet run .
Auf Unix können Sie dateibasierte Apps direkt ausführen und den Namen der Quelldatei in die Befehlszeile anstelle von dotnet run. Sie müssen zwei Änderungen vornehmen:
Festlegen von Ausführungsberechtigungen für die Quelldatei:
chmod +x AsciiArt.csFügen Sie eine Shebang-Direktive (
#!) als erste Zeile derAsciiArt.csDatei hinzu:#!/usr/local/share/dotnet/dotnet run
Die Lage kann dotnet auf verschiedenen Unix-Installationen unterschiedlich sein. Verwenden Sie den Befehl which dotnet , um den dotnet Host in Ihrer Umgebung zu finden.
Alternativ können Sie den .NET-Pfad automatisch aus der PATH-Umgebungsvariable ermitteln:
#!/usr/bin/env dotnet
Nachdem Sie diese beiden Änderungen vorgenommen haben, können Sie das Programm direkt über die Befehlszeile ausführen:
./AsciiArt.cs
Wenn Sie es vorziehen, können Sie die Erweiterung entfernen, damit Sie stattdessen eingeben ./AsciiArt können. Sie können die #! Quelldatei auch dann hinzufügen, wenn Sie Windows verwenden. Die Windows-Befehlszeile unterstützt #!nicht, aber der C#-Compiler ermöglicht diese Direktive in dateibasierten Apps auf allen Plattformen.
Befehlszeilenargumente lesen
Schreiben Sie nun alle Argumente in der Befehlszeile in die Ausgabe.
Ersetzen Sie den aktuellen Inhalt durch
AsciiArt.csden folgenden Code:if (args.Length > 0) { string message = string.Join(' ', args); Console.WriteLine(message); }Sie können diese Version ausführen, indem Sie den folgenden Befehl eingeben:
dotnet run AsciiArt.cs -- This is the command line.Die
--Option gibt an, dass alle folgenden Befehlsargumente an das AsciiArt-Programm übergeben werden sollen. Die ArgumenteThis is the command line.werden als Array von Zeichenfolgen übergeben, wobei jede Zeichenfolge ein Wort ist:This, , ,is,the,commandundline..
Diese Version veranschaulicht die folgenden neuen Konzepte:
- Die Befehlszeilenargumente werden mithilfe der vordefinierten Variablen
argsan das Programm übergeben. DieargsVariable ist ein Array von Zeichenfolgen:string[]. Wenn die Längeargs0 ist, bedeutet dies, dass keine Argumente angegeben wurden. Andernfalls wird jedes Wort in der Argumentliste im entsprechenden Eintrag im Array gespeichert. - Die
string.JoinMethode verknüpft mehrere Zeichenfolgen mit einer einzelnen Zeichenfolge mit dem angegebenen Trennzeichen. In diesem Fall ist das Trennzeichen ein einzelnes Leerzeichen. - Console.WriteLine schreibt die Zeichenfolge in die Standardausgabekonsole, gefolgt von einer neuen Zeile.
Behandeln von Standardeingaben
Dadurch werden Befehlszeilenargumente richtig behandelt. Fügen Sie nun den Code hinzu, um das Lesen von Eingaben von Standardeingaben (stdin) anstelle von Befehlszeilenargumenten zu behandeln.
Fügen Sie der Anweisung, die Sie im vorherigen Code hinzugefügt haben, die
elsefolgendeifKlausel hinzu:else { while (Console.ReadLine() is string line && line.Length > 0) { Console.WriteLine(line); } }Der vorherige Code liest die Konsoleneingabe, bis entweder eine leere Zeile oder eine
nullgelesen wird. (Die Console.ReadLine Methode gibt zurücknull, wenn der Eingabedatenstrom durch Eingabe von STRG+C geschlossen wird.)Testen Sie das Lesen von Standardeingaben, indem Sie eine neue Textdatei im selben Ordner erstellen. Benennen Sie die Datei
input.txt, und fügen Sie die folgenden Zeilen hinzu:Hello from ... dotnet! You can create file-based apps in .NET 10 and C# 14 Have fun writing useful utilitiesHalten Sie die Zeilen kurz, damit sie korrekt formatiert werden, wenn Sie das Feature zur Verwendung von ASCII-Grafiken hinzufügen.
Führen Sie das Programm erneut aus.
Mit Bash:
cat input.txt | dotnet run AsciiArt.csOder mit PowerShell:
Get-Content input.txt | dotnet run AsciiArt.cs
Jetzt kann Ihr Programm entweder Befehlszeilenargumente oder Standardeingaben akzeptieren.
AsciiArt-Ausgabe schreiben
Fügen Sie als Nächstes ein Paket hinzu, das ASCII-Grafiken unterstützt, "Colorful.Console". Wenn Sie einem dateibasierten Programm ein Paket hinzufügen möchten, verwenden Sie die #:package Direktive.
Fügen Sie die folgende Direktive nach der Direktive in der
#!datei AsciiArt.cs hinzu:#:package Colorful.Console@1.2.15Von Bedeutung
Die Version
1.2.15war die neueste Version desColorful.ConsolePakets, als dieses Lernprogramm zuletzt aktualisiert wurde. Überprüfen Sie die NuGet-Seite des Pakets auf die neueste Version, um sicherzustellen, dass Sie eine Paketversion mit den neuesten Sicherheitsupdates verwenden.Ändern Sie stattdessen die Zeilen, die aufgerufen
Console.WriteLinewerden, um dieColorful.Console.WriteAsciiMethode zu verwenden:async Task WriteAsciiArt(AsciiMessageOptions options) { foreach (string message in options.Messages) { Colorful.Console.WriteAscii(message); await Task.Delay(options.Delay); } }Führen Sie das Programm aus, und sie sehen die ASCII-Grafikausgabe anstelle von echoiertem Text.
Prozessbefehlsoptionen
Als Nächstes fügen wir die Befehlszeilenanalyse hinzu. Die aktuelle Version schreibt jedes Wort als eine andere Ausgabezeile. Die Befehlszeilenargumente, die Sie hinzugefügt haben, unterstützen zwei Features:
Anführungszeichen mehrerer Wörter, die in einer Zeile geschrieben werden sollen:
AsciiArt.cs "This is line one" "This is another line" "This is the last line"Fügen Sie eine
--delayOption zum Anhalten zwischen den einzelnen Zeilen hinzu:AsciiArt.cs --delay 1000
Benutzer sollten beide Argumente zusammen verwenden können.
Die meisten Befehlszeilenanwendungen müssen Befehlszeilenargumente analysieren, um Optionen, Befehle und Benutzereingaben effektiv zu verarbeiten. Die System.CommandLine Bibliothek bietet umfassende Funktionen zum Behandeln von Befehlen, Unterbefehlen, Optionen und Argumenten, sodass Sie sich nicht auf die Mechanismen der Analyse von Befehlszeileneingaben, sondern auf die Funktionsweise Ihrer Anwendung konzentrieren können.
Die System.CommandLine Bibliothek bietet mehrere wichtige Vorteile:
- Automatische Hilfetextgenerierung und -validierung.
- Unterstützung für POSIX- und Windows-Befehlszeilenkonventionen.
- Integrierte Funktionen zum Abschließen von Registerkarten.
- Einheitliches Analyseverhalten für alle Anwendungen.
Fügen Sie das
System.CommandLinePaket hinzu. Fügen Sie diese Direktive nach der vorhandenen Paketdirektive hinzu:#:package System.CommandLine@2.0.0Von Bedeutung
Die Version war die neueste Version
2.0.0, als dieses Lernprogramm zuletzt aktualisiert wurde. Wenn eine neuere Version verfügbar ist, verwenden Sie die neueste Version, um sicherzustellen, dass Sie über die neuesten Sicherheitspakete verfügen. Überprüfen Sie die NuGet-Seite des Pakets auf die neueste Version, um sicherzustellen, dass Sie eine Paketversion mit den neuesten Sicherheitsupdates verwenden.Fügen Sie oben in der Datei die erforderlichen Using-Anweisungen hinzu (nach den
#!Anweisungen#:package):using System.CommandLine; using System.CommandLine.Parsing;Definieren Sie das Argument "Verzögerungsoption" und "Nachrichten". Fügen Sie den folgenden Code hinzu, um die
CommandLine.OptionBefehlszeilenoption undCommandLine.Argumentdas Argument darzustellen:Option<int> delayOption = new("--delay") { Description = "Delay between lines, specified as milliseconds.", DefaultValueFactory = parseResult => 100 }; Argument<string[]> messagesArgument = new("Messages") { Description = "Text to render." };In Befehlszeilenanwendungen beginnen Optionen in der Regel mit
--(doppelter Gedankenstrich) und können Argumente akzeptieren. Die--delayOption akzeptiert ein ganzzahliges Argument, das die Verzögerung in Millisekunden angibt. DiemessagesArgumentDefinition definiert, wie alle verbleibenden Token nach der Analyse von Optionen als Text analysiert werden. Jedes Token wird zu einer separaten Zeichenfolge im Array, text kann jedoch zitiert werden, um mehrere Wörter in ein Token einzuschließen. Beispielsweise"This is one message"wird ein einzelnes Token, währendThis is four tokenses zu vier separaten Token wird.Der vorangehende Code definiert den Argumenttyp für die
--delayOption und dass es sich bei den Argumenten um ein Array vonstringWerten handelt. Diese Anwendung hat nur einen Befehl, sodass Sie den Stammbefehl verwenden.Erstellen Sie einen Stammbefehl, und konfigurieren Sie ihn mit der Option und dem Argument. Fügen Sie das Argument und die Option zum Stammbefehl hinzu:
RootCommand rootCommand = new("Ascii Art file-based program sample"); rootCommand.Options.Add(delayOption); rootCommand.Arguments.Add(messagesArgument);Fügen Sie den Code hinzu, um die Befehlszeilenargumente zu analysieren und fehler zu behandeln. Dieser Code überprüft die Befehlszeilenargumente und speichert analysierte Argumente im System.CommandLine.ParseResult Objekt:
ParseResult result = rootCommand.Parse(args); foreach (ParseError parseError in result.Errors) { Console.Error.WriteLine(parseError.Message); } if (result.Errors.Count > 0) { return 1; }
Der vorangehende Code überprüft alle Befehlszeilenargumente. Wenn die Überprüfung fehlschlägt, werden Fehler in die Konsole geschrieben und die App beendet.
Verwenden analysierter Befehlszeilenergebnisse
Beenden Sie nun die App, um die analysierten Optionen zu verwenden und die Ausgabe zu schreiben. Definieren Sie zunächst einen Datensatz, der die analysierten Optionen enthält. Dateibasierte Apps können Typdeklarationen wie Datensätze und Klassen enthalten. Sie müssen nach allen Anweisungen der obersten Ebene und lokalen Funktionen sein.
Fügen Sie eine
recordDeklaration hinzu, um die Nachrichten und den Verzögerungsoptionswert zu speichern:public record AsciiMessageOptions(string[] Messages, int Delay);Fügen Sie die folgende lokale Funktion vor der Datensatzdeklaration hinzu. Diese Methode behandelt Befehlszeilenargumente und Standardeingaben und gibt eine neue Datensatzinstanz zurück:
async Task<AsciiMessageOptions> ProcessParseResults(ParseResult result) { int delay = result.GetValue(delayOption); List<string> messages = [.. result.GetValue(messagesArgument) ?? Array.Empty<string>()]; if (messages.Count == 0) { while (Console.ReadLine() is string line && line.Length > 0) { Colorful.Console.WriteAscii(line); await Task.Delay(delay); } } return new([.. messages], delay); }Erstellen Sie eine lokale Funktion, um die ASCII-Grafik mit der angegebenen Verzögerung zu schreiben. Diese Funktion schreibt jede Nachricht im Datensatz mit der angegebenen Verzögerung zwischen jeder Nachricht:
async Task WriteAsciiArt(AsciiMessageOptions options) { foreach (string message in options.Messages) { Colorful.Console.WriteAscii(message); await Task.Delay(options.Delay); } }Ersetzen Sie die
ifklausel, die Sie zuvor geschrieben haben, durch den folgenden Code, der die Befehlszeilenargumente verarbeitet, und schreiben Sie die Ausgabe:var parsedArgs = await ProcessParseResults(result); await WriteAsciiArt(parsedArgs); return 0;
Sie haben einen record Typ erstellt, der den analysierten Befehlszeilenoptionen und -argumenten Struktur bereitstellt. Neue lokale Funktionen erstellen eine Instanz des Datensatzes und verwenden den Datensatz, um die ASCII-Grafikausgabe zu schreiben.
Testen der endgültigen Anwendung
Testen Sie die Anwendung, indem Sie mehrere verschiedene Befehle ausführen. Wenn Sie Probleme haben, finden Sie hier das fertige Beispiel, um mit dem zu vergleichen, was Sie erstellt haben:If you have trouble, here's the finished sample to compare with what you built:
#!/usr/local/share/dotnet/dotnet run
#:package Colorful.Console@1.2.15
#:package System.CommandLine@2.0.0
using System.CommandLine;
using System.CommandLine.Parsing;
Option<int> delayOption = new("--delay")
{
Description = "Delay between lines, specified as milliseconds.",
DefaultValueFactory = parseResult => 100
};
Argument<string[]> messagesArgument = new("Messages")
{
Description = "Text to render."
};
RootCommand rootCommand = new("Ascii Art file-based program sample");
rootCommand.Options.Add(delayOption);
rootCommand.Arguments.Add(messagesArgument);
ParseResult result = rootCommand.Parse(args);
foreach (ParseError parseError in result.Errors)
{
Console.Error.WriteLine(parseError.Message);
}
if (result.Errors.Count > 0)
{
return 1;
}
var parsedArgs = await ProcessParseResults(result);
await WriteAsciiArt(parsedArgs);
return 0;
async Task<AsciiMessageOptions> ProcessParseResults(ParseResult result)
{
int delay = result.GetValue(delayOption);
List<string> messages = [.. result.GetValue(messagesArgument) ?? Array.Empty<string>()];
if (messages.Count == 0)
{
while (Console.ReadLine() is string line && line.Length > 0)
{
// <WriteAscii>
Colorful.Console.WriteAscii(line);
// </WriteAscii>
await Task.Delay(delay);
}
}
return new([.. messages], delay);
}
async Task WriteAsciiArt(AsciiMessageOptions options)
{
foreach (string message in options.Messages)
{
Colorful.Console.WriteAscii(message);
await Task.Delay(options.Delay);
}
}
public record AsciiMessageOptions(string[] Messages, int Delay);
In diesem Lernprogramm haben Sie gelernt, ein dateibasiertes Programm zu erstellen, in dem Sie das Programm in einer einzigen C#-Datei erstellen. Diese Programme verwenden keine Projektdatei und können die #! Direktive auf Unix-Systemen verwenden. Lernende können diese Programme nach dem Testen unserer Onlinelernprogramme und vor dem Erstellen größerer projektbasierter Apps erstellen. Dateibasierte Apps sind auch eine großartige Plattform für Befehlszeilenprogramme.