Anteckning
Åtkomst till den här sidan kräver auktorisering. Du kan prova att logga in eller ändra kataloger.
Åtkomst till den här sidan kräver auktorisering. Du kan prova att ändra kataloger.
Viktigt!
Filbaserade appar är en funktion i .NET 10, som är en förhandsversion. Viss information gäller förhandsversionsprodukt som kan ändras före lanseringen. Microsoft lämnar inga garantier, uttryckliga eller underförstådda, med avseende på den information som tillhandahålls här.
              Filbaserade appar är program som finns i en enda *.cs fil som skapas och körs utan motsvarande projektfil (*.csproj). Filbaserade appar är idealiska för att lära sig C# eftersom de har mindre komplexitet: Hela programmet lagras i en enda fil. Filbaserade appar är också användbara för att skapa kommandoradsverktyg. På Unix-plattformar kan filbaserade appar köras med hjälp av #! (shebang)-direktiv.
I den här handledningen kommer du att:
- Skapa ett filbaserat program.
- Lägg till Stöd för Unix shebang (#!).
- Läsa kommandoradsargument.
- Hantera standardindata.
- Skriv ASCII-konstutdata.
- Bearbeta kommandoradsargument.
- Använd parsade kommandoradsresultat.
- Testa det slutliga programmet.
Du skapar ett filbaserat program som skriver text som ASCII-konst. Appen finns i en enda fil och använder NuGet-paket som implementerar några av kärnfunktionerna.
Förutsättningar
- Förhandsversionen av .NET 10 SDK. Ladda ned den från nedladdningswebbplatsen för .NET.
- Visual Studio Code. Ladda ned den från Visual Studio Code-startsidan.
- (Valfritt) C# DevKit-tillägget för Visual Studio Code. Ladda ned den från Visual Studio Code Marketplace.
Skapa ett filbaserat program
- Öppna Visual Studio Code och skapa en ny fil med namnet - AsciiArt.cs. Ange följande text:- Console.WriteLine("Hello, world!");
- Spara filen. Öppna sedan den integrerade terminalen i Visual Studio Code och skriv: - dotnet run AsciiArt.cs
Första gången du kör det här programmet dotnet skapar värden den körbara filen från källfilen, lagrar byggartefakter i en tillfällig mapp och kör sedan den körbara filen. Du kan verifiera den här upplevelsen genom att dotnet run AsciiArt.cs skriva igen. Den här gången dotnet avgör värden att den körbara filen är aktuell och kör den körbara filen utan att skapa den igen. Du ser inga build-utdata.
Föregående steg visar att filbaserade appar inte är skriptfiler. Det är C#-källfiler som skapas med hjälp av en genererad projektfil i en tillfällig mapp. En av de utdatarader som visas när du skapade programmet bör se ut ungefär så här (i Windows):
AsciiArt succeeded (7.3s) → AppData\Local\Temp\dotnet\runfile\AsciiArt-85c58ae0cd68371711f06f297fa0d7891d0de82afde04d8c64d5f910ddc04ddc\bin\debug\AsciiArt.dll
På unix-plattformar liknar utdatamappen följande:
AsciiArt succeeded (7.3s) → Library/Application Support/dotnet/runfile/AsciiArt-85c58ae0cd68371711f06f297fa0d7891d0de82afde04d8c64d5f910ddc04ddc/bin/debug/AsciiArt.dll
Utdata anger var de temporära filerna och byggutdata placeras. I den här självstudien, när du redigerar källfilen, dotnet uppdaterar värden den körbara filen innan den körs.
Filbaserade appar är vanliga C#-program. Den enda begränsningen är att de måste skrivas i en källfil. Du kan använda toppnivåinstruktioner eller en klassisk Main metod som startpunkt. Du kan deklarera alla typer: klasser, gränssnitt och structs. Du kan strukturera algoritmerna i ett filbaserat program på samma sätt som i alla C#-program. Du kan till och med deklarera flera namnområden för att organisera koden. Om du upptäcker att ett filbaserat program blir för stort för en enskild fil kan du konvertera det till ett projektbaserat program och dela upp källan i flera filer. Filbaserade appar är ett bra prototypverktyg. Du kan börja experimentera med minimala omkostnader för att bevisa begrepp och bygga algoritmer.
Stöd för Unix shebang (#!)
Anmärkning
Stöd för #! direktiv gäller endast på unix-plattformar. Det finns inget liknande direktiv för Windows att köra ett C#-program direkt. I Windows måste du använda dotnet run på kommandoraden.
På unix kan du köra filbaserade appar direkt och skriva källfilnamnet på kommandoraden i stället för dotnet run. Du måste göra två ändringar:
- Ange körningsbehörigheter för källfilen: - chmod +x AsciiArt.cs
- Lägg till ett shebang-direktiv ( - #!) som den första raden i- AsciiArt.csfilen:- #!/usr/local/share/dotnet/dotnet run
Platsen för dotnet kan vara olika för olika unix-installationer. Använd kommandot whence dotnet för att lokalisera dotnet värden i din miljö.
När du har gjort dessa två ändringar kan du köra programmet direkt från kommandoraden:
./AsciiArt.cs
Om du vill kan du ta bort tillägget så att du kan skriva ./AsciiArt i stället. Du kan lägga till i #! källfilen även om du använder Windows. Windows-kommandoraden stöder #!inte , men C#-kompilatorn tillåter det direktivet i filbaserade appar på alla plattformar.
Läsa kommandoradsargument
Skriv nu alla argument på kommandoraden till utdata.
- Ersätt det aktuella innehållet i - AsciiArt.csmed följande kod:- if (args.Length > 0) { string message = string.Join(' ', args); Console.WriteLine(message); }
- Du kan köra den här versionen genom att skriva följande kommando: - dotnet run AsciiArt.cs -- This is the command line.- Alternativet - --anger att alla följande kommandoargument ska skickas till AsciiArt-programmet. Argumenten- This is the command line.skickas som en matris med strängar, där varje sträng är ett ord:- This,- is,- the,- commandoch- line..
Den här versionen visar dessa nya begrepp:
- Kommandoradsargumenten skickas till programmet med den fördefinierade variabeln args. Variabelnargsär en matris med strängar:string[]. Om längdenargspå är 0 innebär det att inga argument har angetts. Annars lagras varje ord i argumentlistan i motsvarande post i matrisen.
- Metoden string.Joinkopplar flera strängar till en enda sträng med den angivna avgränsaren. I det här fallet är avgränsaren ett enda blanksteg.
- Console.WriteLine skriver strängen till standardutdatakonsolen följt av en ny rad.
Hantera standardindata
Det hanterar kommandoradsargument korrekt. Lägg nu till koden för att hantera läsindata från standardindata (stdin) i stället för kommandoradsargument.
- Lägg till följande - elsesats i -instruktionen- ifsom du lade till i föregående kod:- else { while (Console.ReadLine() is string line && line.Length > 0) { Console.WriteLine(line); } }- Föregående kod läser konsolens indata tills antingen en tom rad eller en - nulllästs. (Metoden Console.ReadLine returnerar- nullom indataströmmen stängs genom att skriva ctrl+C.)
- Testa att läsa standardindata genom att skapa en ny textfil i samma mapp. Namnge filen - input.txtoch lägg till följande rader:- Hello from ... dotnet! You can create file-based apps in .NET 10 and C# 14 Have fun writing useful utilities- Håll linjerna korta så att de formateras korrekt när du lägger till funktionen för att använda ASCII-konst. 
- Kör programmet igen. - Med bash: - cat input.txt | dotnet run AsciiArt.cs- Eller med PowerShell: - Get-Content input.txt | dotnet run AsciiArt.cs
Nu kan programmet acceptera antingen kommandoradsargument eller standardindata.
Skriva ASCII Art-utdata
Lägg sedan till ett paket som stöder ASCII-konst, Colorful.Console. Om du vill lägga till ett paket i ett filbaserat program använder #:package du direktivet.
- Lägg till följande direktiv efter - #!direktivet i din AsciiArt.cs-fil:- #:package Colorful.Console@1.2.15- Viktigt! - Versionen - 1.2.15var den senaste versionen av- Colorful.Consolepaketet när den här självstudien senast uppdaterades. Kontrollera paketets NuGet-sida för den senaste versionen för att se till att du använder en paketversion med de senaste säkerhetskorrigeringarna.
- Ändra de rader som anropar - Console.WriteLineför att använda- Colorful.Console.WriteAsciimetoden i stället:- async Task WriteAsciiArt(AsciiMessageOptions options) { foreach (string message in options.Messages) { Colorful.Console.WriteAscii(message); await Task.Delay(options.Delay); } }
- Kör programmet och du ser ASCII-konstutdata i stället för upprepad text. 
Processkommandoalternativ
Nu ska vi lägga till kommandoradsparsning. Den aktuella versionen skriver varje ord som en annan rad med utdata. De kommandoradsargument som du har lagt till stöder två funktioner:
- Citera flera ord som ska skrivas på en rad: - AsciiArt.cs "This is line one" "This is another line" "This is the last line"
- Lägg till ett - --delayalternativ för att pausa mellan varje rad:- AsciiArt.cs --delay 1000
Användarna bör kunna använda båda argumenten tillsammans.
De flesta kommandoradsprogram behöver parsa kommandoradsargument för att hantera alternativ, kommandon och användarindata effektivt. 
              BiblioteketSystem.CommandLine innehåller omfattande funktioner för att hantera kommandon, underkommandon, alternativ och argument, så att du kan koncentrera dig på vad ditt program gör i stället för mekaniken för att parsa kommandoradsindata.
Biblioteket System.CommandLine har flera viktiga fördelar:
- Automatisk textgenerering och validering av hjälp.
- Stöd för POSIX- och Windows-kommandoradskonventioner.
- Inbyggda funktioner för flikkomplettering.
- Konsekvent parsningsbeteende mellan program.
- System.CommandLineLägg till paketet. Lägg till det här direktivet efter det befintliga paketdirektivet:- #:package System.CommandLine@2.0.0-beta6- Viktigt! - Versionen - 2.0.0-beta6var den senaste versionen när den här självstudien senast uppdaterades. Om det finns en nyare version tillgänglig använder du den senaste versionen för att se till att du har de senaste säkerhetspaketen. Kontrollera paketets NuGet-sida för den senaste versionen för att se till att du använder en paketversion med de senaste säkerhetskorrigeringarna.
- Lägg till nödvändiga användningsinstruktioner överst i filen (efter direktiven - #!och- #:package):- using System.CommandLine; using System.CommandLine.Parsing;
- Definiera argumentet fördröjning och meddelanden. Lägg till följande kod för att skapa objekten - CommandLine.Optionoch- CommandLine.Argumentför att representera kommandoradsalternativet och argumentet:- Option<int> delayOption = new("--delay") { Description = "Delay between lines, specified as milliseconds.", DefaultValueFactory = parseResult => 100 }; Argument<string[]> messagesArgument = new("Messages") { Description = "Text to render." };- I kommandoradsprogram börjar alternativen vanligtvis med - --(dubbel bindestreck) och kan acceptera argument. Alternativet- --delayaccepterar ett heltalsargument som anger fördröjningen i millisekunder. Definierar- messagesArgumenthur eventuella återstående token efter alternativ parsas som text. Varje token blir en separat sträng i matrisen, men text kan citeras för att inkludera flera ord i en token. Till exempel- "This is one message"blir en enda token, medan- This is four tokensblir fyra separata token.- Föregående kod definierar argumenttypen för - --delayalternativet och att argumenten är en matris med- stringvärden. Det här programmet har bara ett kommando, så du använder rotkommandot.
- Skapa ett rotkommando och konfigurera det med alternativet och argumentet. Lägg till argumentet och alternativet i rotkommandot: - RootCommand rootCommand = new("Ascii Art file-based program sample"); rootCommand.Options.Add(delayOption); rootCommand.Arguments.Add(messagesArgument);
- Lägg till koden för att parsa kommandoradsargumenten och hantera eventuella fel. Den här koden validerar kommandoradsargumenten och lagrar parsade argument i System.CommandLine.ParseResult objektet: - ParseResult result = rootCommand.Parse(args); foreach (ParseError parseError in result.Errors) { Console.Error.WriteLine(parseError.Message); } if (result.Errors.Count > 0) { return 1; }
Föregående kod verifierar alla kommandoradsargument. Om verifieringen misslyckas skrivs fel till konsolen och appen avslutas.
Använda parsade kommandoradsresultat
Slutför nu appen för att använda de parsade alternativen och skriva utdata. Definiera först en post som ska innehålla de parsade alternativen. Filbaserade appar kan innehålla typdeklarationer, till exempel poster och klasser. De måste vara efter alla toppnivåinstruktioner och lokala funktioner.
- Lägg till en - recorddeklaration för att lagra meddelandena och alternativet för fördröjning:- public record AsciiMessageOptions(string[] Messages, int Delay);
- Lägg till följande lokala funktion före postdeklarationen. Den här metoden hanterar både kommandoradsargument och standardindata och returnerar en ny postinstans: - 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); }
- Skapa en lokal funktion för att skriva ASCII-konsten med den angivna fördröjningen. Den här funktionen skriver varje meddelande i posten med den angivna fördröjningen mellan varje meddelande: - async Task WriteAsciiArt(AsciiMessageOptions options) { foreach (string message in options.Messages) { Colorful.Console.WriteAscii(message); await Task.Delay(options.Delay); } }
- ifErsätt satsen som du skrev tidigare med följande kod som bearbetar kommandoradsargumenten och skriver utdata:- var parsedArgs = await ProcessParseResults(result); await WriteAsciiArt(parsedArgs); return 0;
Du har skapat en record typ som ger struktur åt de parsade kommandoradsalternativen och argumenten. Nya lokala funktioner skapar en instans av posten och använder posten för att skriva ASCII-konstutdata.
Testa det slutliga programmet
Testa programmet genom att köra flera olika kommandon. Om du har problem kan du jämföra det här exemplet med det du har skapat:
#!/usr/local/share/dotnet/dotnet run
#:package Colorful.Console@1.2.15
#:package System.CommandLine@2.0.0-beta6
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);
I den här självstudien har du lärt dig att skapa ett filbaserat program, där du skapar programmet i en enda C#-fil. De här programmen använder inte en projektfil och kan använda #! direktivet på unix-system. Elever kan skapa dessa program efter att ha provat våra online-självstudier och innan de skapar större projektbaserade appar. Filbaserade appar är också en bra plattform för kommandoradsverktyg.