Notitie
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen u aan te melden of de directory te wijzigen.
Voor toegang tot deze pagina is autorisatie vereist. U kunt proberen de mappen te wijzigen.
Op bestanden gebaseerde apps zijn programma's die zijn opgenomen in één *.cs bestand dat zonder een bijbehorend projectbestand (*.csproj) wordt gebouwd en uitgevoerd. Op bestanden gebaseerde apps zijn ideaal voor het leren van C# omdat ze minder complex zijn: het hele programma wordt opgeslagen in één bestand. Op bestanden gebaseerde apps zijn ook handig voor het bouwen van opdrachtregelprogramma's. Op Unix-platforms kunnen op bestanden gebaseerde apps worden uitgevoerd met behulp van #! (shebang) -instructies.
In deze handleiding leert u:
- Maak een programma op basis van bestanden.
- Voeg ondersteuning voor Unix shebang (
#!) toe. - Opdrachtregelargumenten lezen.
- Standaardinvoer verwerken.
- AsCII-kunstuitvoer schrijven.
- Opdrachtregelargumenten verwerken.
- Gebruik geparseerde opdrachtregelresultaten.
- Test de laatste toepassing.
U bouwt een programma op basis van bestanden dat tekst schrijft als ASCII-illustratie. De app bevindt zich in één bestand en maakt gebruik van NuGet-pakketten die enkele kernfuncties implementeren.
Vereiste voorwaarden
- De .NET 10 SDK. Download het vanaf de .NET-downloadsite.
- Visual Studio Code. Download deze vanaf de startpagina van Visual Studio Code.
- (Optioneel) De C#DevKit-extensie voor Visual Studio Code. Download deze vanuit de Visual Studio Code-marketplace.
Een programma op basis van bestanden maken
Open Visual Studio Code en maak een nieuw bestand met de naam
AsciiArt.cs. Voer de volgende tekst in:Console.WriteLine("Hello, world!");Sla het bestand op. Open vervolgens de geïntegreerde terminal in Visual Studio Code en typ:
dotnet run AsciiArt.cs
De eerste keer dat u dit programma uitvoert, bouwt de dotnet host het uitvoerbare bestand op vanuit uw bronbestand, slaat buildartefacten op in een tijdelijke map en voert vervolgens het gemaakte uitvoerbare bestand uit. U kunt deze ervaring controleren door opnieuw te typen dotnet run AsciiArt.cs . Deze keer bepaalt de dotnet host dat het uitvoerbare bestand actueel is en voert het uitvoerbare bestand uit zonder het opnieuw te bouwen. U ziet geen build-uitvoer.
In de voorgaande stappen ziet u dat op bestanden gebaseerde apps geen scriptbestanden zijn. Het zijn C#-bronbestanden die zijn gebouwd met behulp van een gegenereerd projectbestand in een tijdelijke map. Een van de uitvoerregels die worden weergegeven tijdens het bouwen van het programma, moet er ongeveer als volgt uitzien (in Windows):
AsciiArt succeeded (7.3s) → AppData\Local\Temp\dotnet\runfile\AsciiArt-85c58ae0cd68371711f06f297fa0d7891d0de82afde04d8c64d5f910ddc04ddc\bin\debug\AsciiArt.dll
Op UNIX-platforms is de uitvoermap vergelijkbaar met:
AsciiArt succeeded (7.3s) → Library/Application Support/dotnet/runfile/AsciiArt-85c58ae0cd68371711f06f297fa0d7891d0de82afde04d8c64d5f910ddc04ddc/bin/debug/AsciiArt.dll
Deze uitvoer geeft aan waar de tijdelijke bestanden en build-uitvoer worden geplaatst. Tijdens deze zelfstudie wordt het uitvoerbare bestand bijgewerkt wanneer u het bronbestand dotnet bewerkt voordat het wordt uitgevoerd.
Op bestanden gebaseerde apps zijn reguliere C#-programma's. De enige beperking is dat ze in één bronbestand moeten worden geschreven. U kunt instructies op het hoogste niveau of een klassieke Main methode gebruiken als toegangspunt. U kunt elk type declareren: klassen, interfaces en structs. U kunt de algoritmen in een bestandsprogramma op dezelfde manier structuren als in elk C#-programma. U kunt zelfs meerdere naamruimten declareren om uw code te ordenen. Als u merkt dat een programma op basis van bestanden te groot wordt voor één bestand, kunt u het converteren naar een projectprogramma en de bron splitsen in meerdere bestanden. Op bestanden gebaseerde apps zijn een geweldig prototypeprogramma. U kunt experimenteren met minimale overhead om concepten te bewijzen en algoritmen te bouwen.
Ondersteuning voor Unix shebang (#!)
Opmerking
Ondersteuning voor #! richtlijnen is alleen van toepassing op UNIX-platforms. Er is geen vergelijkbare instructie voor Windows om rechtstreeks een C#-programma uit te voeren. In Windows moet u op de opdrachtregel gebruiken dotnet run .
Op unix kunt u apps op basis van bestanden rechtstreeks uitvoeren, waarbij u de naam van het bronbestand op de opdrachtregel typt in plaats van dotnet run. U moet twee wijzigingen aanbrengen:
Uitvoermachtigingen instellen voor het bronbestand:
chmod +x AsciiArt.csVoeg een shebang(
#!)-instructie toe als de eerste regel van hetAsciiArt.csbestand:#!/usr/local/share/dotnet/dotnet run
De locatie kan dotnet verschillen op verschillende UNIX-installaties. Gebruik de opdracht which dotnet om de dotnet host in uw omgeving te vinden.
Alternatief kunt u met #!/usr/bin/env dotnet het dotnet-pad automatisch bepalen vanuit de omgevingsvariabele PATH:
#!/usr/bin/env dotnet
Nadat u deze twee wijzigingen hebt aangebracht, kunt u het programma rechtstreeks vanaf de opdrachtregel uitvoeren:
./AsciiArt.cs
Als u wilt, kunt u de extensie verwijderen, zodat u in plaats daarvan kunt typen ./AsciiArt . U kunt het #! aan uw bronbestand toevoegen, zelfs als u Windows gebruikt. De Windows-opdrachtregel biedt geen ondersteuning #!voor de C#-compiler, maar de C#-compiler staat deze instructie toe in apps op basis van bestanden op alle platforms.
Opdrachtregelargumenten lezen
Schrijf nu alle argumenten op de opdrachtregel naar de uitvoer.
Vervang de huidige inhoud door
AsciiArt.csde volgende code:if (args.Length > 0) { string message = string.Join(' ', args); Console.WriteLine(message); }U kunt deze versie uitvoeren door de volgende opdracht te typen:
dotnet run AsciiArt.cs -- This is the command line.De
--optie geeft aan dat alle volgende opdrachtargumenten moeten worden doorgegeven aan het AsciiArt-programma. De argumentenThis is the command line.worden doorgegeven als een matrix van tekenreeksen, waarbij elke tekenreeks één woord is:This,is,the,commandenline..
In deze versie ziet u de volgende nieuwe concepten:
- De opdrachtregelargumenten worden doorgegeven aan het programma met behulp van de vooraf gedefinieerde variabele
args. Deargsvariabele is een matrix met tekenreeksen:string[]. Als de lengte vanargs0 is, betekent dit dat er geen argumenten zijn opgegeven. Anders wordt elk woord in de lijst met argumenten opgeslagen in de bijbehorende vermelding in de matrix. - Met
string.Joinde methode worden meerdere tekenreeksen samengevoegd tot één tekenreeks, met het opgegeven scheidingsteken. In dit geval is het scheidingsteken één spatie. - Console.WriteLine schrijft de tekenreeks naar de standaarduitvoerconsole, gevolgd door een nieuwe regel.
Standaardinvoer verwerken
Hiermee worden opdrachtregelargumenten correct verwerkt. Voeg nu de code toe om het lezen van invoer van standaardinvoer (stdin) te verwerken in plaats van opdrachtregelargumenten.
Voeg de volgende
elsecomponent toe aan deifinstructie die u in de voorgaande code hebt toegevoegd:else { while (Console.ReadLine() is string line && line.Length > 0) { Console.WriteLine(line); } }Met de voorgaande code wordt de consoleinvoer gelezen totdat een lege regel of een
nullregel wordt gelezen. (De Console.ReadLine methode retourneertnullals de invoerstroom wordt gesloten door Ctrl+C te typen.)Test standaardinvoer voor lezen door een nieuw tekstbestand in dezelfde map te maken. Geef het bestand
input.txteen naam en voeg de volgende regels toe:Hello from ... dotnet! You can create file-based apps in .NET 10 and C# 14 Have fun writing useful utilitiesHoud de lijnen kort zodat ze correct worden opgemaakt wanneer u de functie toevoegt om ASCII-illustraties te gebruiken.
Voer het programma opnieuw uit.
Met bash:
cat input.txt | dotnet run AsciiArt.csOf met PowerShell:
Get-Content input.txt | dotnet run AsciiArt.cs
Uw programma kan nu opdrachtregelargumenten of standaardinvoer accepteren.
ASCII Art-uitvoer schrijven
Voeg vervolgens een pakket toe dat ONDERSTEUNING biedt voor ASCII art, Colorful.Console. Als u een pakket wilt toevoegen aan een programma op basis van bestanden, gebruikt u de #:package instructie.
Voeg de volgende instructie toe na de
#!instructie in uw AsciiArt.cs bestand:#:package Colorful.Console@1.2.15Belangrijk
De versie
1.2.15was de nieuwste versie van het pakket toen deze zelfstudie voor hetColorful.Consolelaatst werd bijgewerkt. Controleer de NuGet-pagina van het pakket voor de nieuwste versie om ervoor te zorgen dat u een pakketversie gebruikt met de meest recente beveiligingsoplossingen.Wijzig in plaats daarvan de regels die aanroepen
Console.WriteLineom deColorful.Console.WriteAsciimethode te gebruiken:async Task WriteAsciiArt(AsciiMessageOptions options) { foreach (string message in options.Messages) { Colorful.Console.WriteAscii(message); await Task.Delay(options.Delay); } }Voer het programma uit en u ziet de uitvoer van ASCII-afbeeldingen in plaats van echotekst.
Opties voor procesopdracht
Vervolgens gaan we opdrachtregelparsering toevoegen. De huidige versie schrijft elk woord als een andere uitvoerregel. De opdrachtregelargumenten die u hebt toegevoegd, ondersteunen twee functies:
Citeer meerdere woorden die op één regel moeten worden geschreven:
AsciiArt.cs "This is line one" "This is another line" "This is the last line"Voeg een
--delayoptie toe om tussen elke regel te onderbreken:AsciiArt.cs --delay 1000
Gebruikers moeten beide argumenten samen kunnen gebruiken.
De meeste opdrachtregeltoepassingen moeten opdrachtregelargumenten parseren om opties, opdrachten en gebruikersinvoer effectief te verwerken. De System.CommandLine bibliotheek biedt uitgebreide mogelijkheden voor het afhandelen van opdrachten, subopdrachten, opties en argumenten, zodat u zich kunt concentreren op wat uw toepassing doet in plaats van de mechanica van het parseren van opdrachtregelinvoer.
De System.CommandLine bibliotheek biedt verschillende belangrijke voordelen:
- Automatisch genereren en valideren van Help-tekst.
- Ondersteuning voor POSIX- en Windows-opdrachtregelconventies.
- Ingebouwde mogelijkheden voor het voltooien van tabbladen.
- Consistent parseringsgedrag voor toepassingen.
Voeg het
System.CommandLinepakket toe. Voeg deze richtlijn toe na de bestaande pakketrichtlijn:#:package System.CommandLine@2.0.0Belangrijk
De versie was de nieuwste versie
2.0.0toen deze zelfstudie voor het laatst werd bijgewerkt. Als er een nieuwere versie beschikbaar is, gebruikt u de nieuwste versie om ervoor te zorgen dat u over de nieuwste beveiligingspakketten beschikt. Controleer de NuGet-pagina van het pakket voor de nieuwste versie om ervoor te zorgen dat u een pakketversie gebruikt met de meest recente beveiligingsoplossingen.Voeg de benodigde using-instructies toe boven aan het bestand (na de
#!en#:packageinstructies):using System.CommandLine; using System.CommandLine.Parsing;Definieer de vertragingsoptie en het argument berichten. Voeg de volgende code toe om de
CommandLine.OptionenCommandLine.Argumentobjecten te maken die de opdrachtregeloptie en het argument vertegenwoordigen: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 opdrachtregeltoepassingen beginnen de opties meestal met
--(dubbel streepje) en kunnen argumenten worden geaccepteerd. De--delayoptie accepteert een geheel getalargument dat de vertraging in milliseconden aangeeft. HiermeemessagesArgumentdefinieert u hoe alle resterende tokens na opties worden geparseerd als tekst. Elk token wordt een afzonderlijke tekenreeks in de matrix, maar tekst kan worden aanhalingstekens om meerdere woorden in één token op te nemen. Wordt bijvoorbeeld"This is one message"één token, terwijlThis is four tokenser vier afzonderlijke tokens worden.De voorgaande code definieert het argumenttype voor de
--delayoptie en dat de argumenten een matrix metstringwaarden zijn. Deze toepassing heeft slechts één opdracht, dus u gebruikt de hoofdopdracht.Maak een hoofdopdracht en configureer deze met de optie en het argument. Voeg het argument en de optie toe aan de hoofdopdracht:
RootCommand rootCommand = new("Ascii Art file-based program sample"); rootCommand.Options.Add(delayOption); rootCommand.Arguments.Add(messagesArgument);Voeg de code toe om de opdrachtregelargumenten te parseren en eventuele fouten af te handelen. Met deze code worden de opdrachtregelargumenten gevalideerd en worden geparseerde argumenten opgeslagen in het System.CommandLine.ParseResult object:
ParseResult result = rootCommand.Parse(args); foreach (ParseError parseError in result.Errors) { Console.Error.WriteLine(parseError.Message); } if (result.Errors.Count > 0) { return 1; }
Met de voorgaande code worden alle opdrachtregelargumenten gevalideerd. Als de validatie mislukt, worden fouten naar de console geschreven en wordt de app afgesloten.
Geparseerde opdrachtregelresultaten gebruiken
Voltooi nu de app om de geparseerde opties te gebruiken en de uitvoer te schrijven. Definieer eerst een record voor het opslaan van de geparseerde opties. Op bestanden gebaseerde apps kunnen typedeclaraties bevatten, zoals records en klassen. Ze moeten na alle instructies op het hoogste niveau en lokale functies zijn.
Voeg een
recorddeclaratie toe om de berichten en de waarde van de vertragingsoptie op te slaan:public record AsciiMessageOptions(string[] Messages, int Delay);Voeg de volgende lokale functie toe vóór de recorddeclaratie. Deze methode verwerkt zowel opdrachtregelargumenten als standaardinvoer en retourneert een nieuw recordexemplaren:
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); }Maak een lokale functie om de ASCII-illustratie met de opgegeven vertraging te schrijven. Met deze functie wordt elk bericht in de record geschreven met de opgegeven vertraging tussen elk bericht:
async Task WriteAsciiArt(AsciiMessageOptions options) { foreach (string message in options.Messages) { Colorful.Console.WriteAscii(message); await Task.Delay(options.Delay); } }Vervang de
ifcomponent die u eerder hebt geschreven door de volgende code waarmee de opdrachtregelargumenten worden verwerkt en de uitvoer wordt geschreven:var parsedArgs = await ProcessParseResults(result); await WriteAsciiArt(parsedArgs); return 0;
U hebt een record type gemaakt dat structuur biedt aan de geparseerde opdrachtregelopties en -argumenten. Nieuwe lokale functies maken een exemplaar van de record en gebruiken de record om de ASCII-kunstuitvoer te schrijven.
De laatste toepassing testen
Test de toepassing door verschillende opdrachten uit te voeren. Als u problemen ondervindt, is dit het voltooide voorbeeld om te vergelijken met wat u hebt gemaakt:
#!/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 deze zelfstudie hebt u geleerd hoe u een op bestanden gebaseerd programma bouwt, waarbij u het programma in één C#-bestand bouwt. Deze programma's gebruiken geen projectbestand en kunnen de #! instructie op UNIX-systemen gebruiken. Cursisten kunnen deze programma's maken nadat ze onze online zelfstudies hebben geprobeerd en voordat ze grotere projectgebaseerde apps bouwen. Op bestanden gebaseerde apps zijn ook een geweldig platform voor opdrachtregelprogramma's.