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 einzigen *.cs Datei enthalten sind, die Sie erstellen und ohne eine entsprechende Projektdatei (*.csproj) ausführen. 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 Sie dateibasierte Apps mithilfe #! von (Shebang)- Direktiven ausführen.
In diesem Tutorial führen Sie Folgendes durch:
- Erstellen Sie eine dateibasierte App.
- Unterstützung für Unix-Shebang (
#!) hinzufügen. - Befehlszeilenargumente lesen.
- Standard-Eingaben bearbeiten.
- Schreiben der ASCII-Grafikausgabe.
- Verarbeiten von Befehlszeilenargumenten.
- Verwenden Sie analysierte Befehlszeilenergebnisse.
- Testen Sie die endgültige Anwendung.
Sie erstellen eine dateibasierte App, die Text als ASCII-Grafik schreibt. Die App ist in einer einzelnen Datei enthalten, verwendet NuGet-Pakete und implementiert Kernfeatures.
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 einer dateibasierten App
Ö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 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 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. Sie sind C#-Quelldateien, die der dotnet Host mithilfe einer generierten Projektdatei in einem temporären Ordner erstellt. Eine der Ausgabezeilen, die beim Erstellen des Programms angezeigt werden, 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 Host dotnet die ausführbare Datei jedes Mal, wenn Sie die Quelldatei bearbeiten, und dies geschieht bevor sie ausgeführt wird.
Dateibasierte Apps sind normale C#-Programme. Die einzige Einschränkung besteht darin, dass Sie sie in einer Quelldatei schreiben 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 einer dateibasierten App genauso strukturieren, wie Sie es in jedem C#-Programm tun würden. Sie können sogar mehrere Namespaces deklarieren, um Ihren Code zu organisieren. Wenn Sie feststellen, dass eine dateibasierte App für eine einzelne Datei zu groß wird, können Sie sie 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 #! Richtlinien gilt nur auf Unix-Plattformen. Es gibt keine ähnliche Direktive für Windows, um ein C#-Programm direkt auszuführen. Unter Windows müssen Sie dotnet in der Befehlszeile verwenden.
Führen Sie auf Unix dateibasierte Apps direkt aus, indem Sie nur den Quelldateinamen eingeben. Geben Sie anstelle der Verwendung dotnet AsciiArt.csden Namen der Quelldatei in die Befehlszeile ein. Sie müssen zwei Änderungen vornehmen:
Legen Sie Ausführungsberechtigungen für die Quelldatei fest:
chmod +x AsciiArt.csFügen Sie eine Shebang-Direktive (
#!) als erste Zeile derAsciiArt.csDatei hinzu:#!/usr/local/share/dotnet/dotnet
Der Standort dotnet kann 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 #! in Ihre Quelldatei einfügen, auch 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 von
AsciiArt.csmit dem 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 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 vordefinierte Variable
argsübergibt die Befehlszeilenargumente an das Programm. DieargsVariable ist ein Array von Zeichenfolgen:string[]. Wenn die Längeargs0 ist, wurden keine Argumente angegeben. 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.
Standard-Eingaben verarbeiten
Der vorangehende Code behandelt Befehlszeilenargumente ordnungsgemäß. Fügen Sie nun den Code hinzu, um das Lesen von Eingaben von der Standardeingabe (stdin) anstelle von Befehlszeilenargumenten zu behandeln.
Fügen Sie die folgende
elseKlausel zu derifAnweisung hinzu, die Sie im vorherigen Code hinzugefügt haben.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.
Mithilfe von Bash:
cat input.txt | dotnet AsciiArt.csOder mithilfe von PowerShell:
Get-Content input.txt | dotnet AsciiArt.cs
Jetzt kann Ihr Programm entweder Befehlszeilenargumente oder Standardeingaben akzeptieren.
Schreiben einer ASCII-Grafikausgabe
Fügen Sie als Nächstes ein Paket hinzu, das ASCII-Grafiken unterstützt, "Colorful.Console". Verwenden Sie die #:package Direktive, um einer dateibasierten App ein Paket hinzuzufügen.
Fügen Sie die folgende Direktive nach der
#!-Direktive in IhrerAsciiArt.cs-Datei 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 die Zeilen, die
Console.WriteLineaufrufen, sodass stattdessen dieColorful.Console.WriteAscii-Methode verwendet wird.Colorful.Console.WriteAscii(line);Führen Sie das Programm aus. Die ASCII-Grafikausgabe wird anstelle von echoiertem Text angezeigt.
Prozessbefehlsoptionen
Fügen Sie als Nächstes die Befehlszeilenanalyse hinzu. Die aktuelle Version schreibt jedes Wort als separate Ausgabezeile. Die Befehlszeilenargumente, die Sie hinzufügen, unterstützen zwei Features:
Zitieren Sie mehrere Wörter, die in eine 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 können beide Argumente zusammen verwenden.
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. Sie können sich nicht auf die Mechanismen der Analyse von Befehlszeileneingaben, sondern auf die Funktionsweise Ihrer Anwendung konzentrieren.
Die System.CommandLine Bibliothek bietet mehrere wichtige Vorteile:
- Automatische Hilfetextgenerierung und -validierung.
- Unterstützung für POSIX- und Windows-Befehlszeilenkonventionen.
- Eingebaute Funktionen zur automatischen Vervollständigung.
- 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
2.0.0war die neueste Version, 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
#!und#:packageAnweisungen):using System.CommandLine; using System.CommandLine.Parsing;Definieren Sie das Argument "Verzögerungsoption" und "Nachrichten". Fügen Sie den folgenden Code hinzu, um die Objekte
CommandLine.OptionundCommandLine.Argumentzu erstellen, die die Befehlszeilenoption und das Argument darstellen: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 wird"This is one message"zu einem einzelnen Token, währendThis is four tokenszu 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 app 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, schreibt die App Fehler in die Konsole und beendet sie.
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 Top-Level-Anweisungen und lokalen Funktionen kommen.
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 schreibt 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/bin/env dotnet
#: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 app 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, eine dateibasierte App zu erstellen, in der 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.