C#-Dateien direkt mit `dotnet run app.cs` ausführen
(devblogs.microsoft.com)- Seit .NET 10 Preview 4 gibt es nun die Möglichkeit, eine einzelne C#-Datei direkt mit
dotnet run app.csauszuführen, sodass C#-Code auch ohne Projektdatei ausgeführt werden kann - Dank dateibasierter Apps (file-based apps) werden einfache Skriptausführung, Tests und das Ausprobieren von Ideen ähnlich wie in Python oder JavaScript deutlich einfacher
- Auch NuGet-Paketverweise, SDK-Angaben und Build-Eigenschaften lassen sich über Direktiven in der Datei verwalten, was die Entwicklungsflexibilität erhöht
- Mit shebang-Unterstützung ist die Nutzung unter Unix-artigen Systemen auch für CLI-Utilities und Automatisierungsskripte möglich
- Bei Bedarf ist eine nahtlose Umwandlung in eine projektbasierte App möglich, sodass sich der Weg vom Lernen und Prototyping bis zur vollwertigen App-Entwicklung natürlich fortsetzen lässt
Was ist dotnet run app.cs?
- Bisher war zum Ausführen von C#-Code mit der
dotnet-CLI zwingend eine Projektstruktur (.csproj) erforderlich - Jetzt ist die direkte Ausführung schon mit einer einzelnen .cs-Datei möglich, was die Einstiegshürde deutlich senkt
- Das eignet sich für viele Einsatzfälle wie Skriptsprachen, Automatisierung, Experimente und Lernen
- Durch die CLI-Integration kann es sofort mit
dotnetverwendet werden, ohne zusätzliche Tools zu installieren - Wenn der Code wächst, lässt er sich mit derselben Sprache und denselben Tools zu einer projektbasierten App erweitern
Unterstützung für Direktiven auf Dateiebene
- Auch in dateibasierten Apps lassen sich zentrale Projekteinstellungen direkt als Direktiven in der .cs-Datei deklarieren
-
NuGet-Paketverweise
- Mit der Direktive
#:packagekönnen NuGet-Pakete direkt referenziert werden- Beispiel:
#:package Humanizer@2.14.1 using Humanizer; var dotNet9Released = DateTimeOffset.Parse("2024-12-03"); var since = DateTimeOffset.Now - dotNet9Released; Console.WriteLine($"It has been {since.Humanize()} since .NET 9 was released.");
- Beispiel:
- Mit der Direktive
-
SDK festlegen
- Mit der Direktive
#:sdkkann der SDK-Typ angegeben werden- Beispiel:
#:sdk Microsoft.NET.Sdk.Web - Damit lassen sich auch ASP.NET-Core-Funktionen aktivieren, etwa minimale APIs oder MVC
- Beispiel:
- Mit der Direktive
-
MSBuild-Eigenschaften festlegen
- Mit
#:propertylassen sich Build-Eigenschaften direkt setzen- Beispiel:
#:property LangVersion preview
- Beispiel:
- Mit
-
shebang-Unterstützung für Shell-Skripte
- Wenn am Dateianfang
#!/usr/bin/dotnet runsteht, kann die Datei auf Unix-artigen Systemen direkt als ausführbare Datei verwendet werden- Beispiel:
#!/usr/bin/dotnet run Console.WriteLine("Hello from a C# script!"); - Nach dem Setzen der Ausführungsrechte direkt starten:
chmod +x app.cs ./app.cs
- Beispiel:
- Wenn am Dateianfang
Umwandlung in eine projektbasierte App
- Wenn die App größer wird oder mehr Funktionen benötigt, kann sie mit dem Befehl
dotnet project convert app.cseinfach in ein Projekt umgewandelt werden - Direktiven werden dabei automatisch in Eigenschaften, Verweise usw. der
.csproj-Datei überführt -
Beispiel für die Umwandlung
- Eine Datei wie diese:
#:sdk Microsoft.NET.Sdk.Web #:package Microsoft.AspNetCore.OpenApi@10.*-* var builder = WebApplication.CreateBuilder(); builder.Services.AddOpenApi(); var app = builder.Build(); app.MapGet("/", () => "Hello, world!"); app.Run();
- Eine Datei wie diese:
-
- Ergebnis der Umwandlung:
<Project Sdk="Microsoft.NET.Sdk.Web"> <PropertyGroup> <TargetFramework>net10.0</TargetFramework> <ImplicitUsings>enable</ImplicitUsings> <Nullable>enable</Nullable> </PropertyGroup> <ItemGroup> <PackageReference Include="Microsoft.AspNetCore.OpenApi" Version="10.*-*" /> </ItemGroup> </Project>
Unterschiede zu bisherigen C#-Skriptansätzen
- Bisher war die Ausführung von C#-Skripten zwar über Community-Tools wie CS-Script, dotnet-script oder Cake möglich, erforderte aber separate Installation und Konfiguration
- Jetzt kann Code ohne zusätzliche Installation oder speziellen Modus direkt mit demselben C#-Compiler und derselben Sprache ausgeführt werden, ohne Einstiegshürden
Erste Schritte
- .NET 10 Preview 4 installieren
- Bei Nutzung von Visual Studio Code müssen C# Dev Kit und die neueste Prerelease-Version der C#-Erweiterung (2.79.8 oder höher) installiert sein
- Eine
.cs-Datei anlegen und direkt Code schreiben - Im Terminal
dotnet run hello.csausführen - Bei Bedarf mit
dotnet project convert hello.csin ein Projekt umwandeln
Mehr erfahren
Nächste Schritte
- Geplant sind Unterstützung für dateibasierte Apps in VS Code, bessere IntelliSense für Direktiven, Performance-Verbesserungen und stärkere Debugging-Unterstützung
- Auch zusätzliche Funktionen wie Unterstützung für mehrere Dateien und schnellere Ausführung sind in Entwicklung
dotnet run app.csmacht C# leichter zugänglich und liefert gleichzeitig die volle Stärke von .NET- Es schafft die Grundlage, um schneller von Prototyping und Schulung zur produktiven Entwicklung zu wechseln
4 Kommentare
Die DX, die eine Autovervollständigungs-Erfahrung auf Basis von File-based App bietet, ist zwar in der neuesten Version der C#-Erweiterung verfügbar, ursprünglich hatte Microsoft die Erweiterung jedoch nicht an anderer Stelle als im VS Code Marketplace veröffentlicht.
Um diese Unannehmlichkeit zu beseitigen, habe ich nur den C#-Extension-Teil (den Teil unter MIT-Lizenz) statt des C# Dev Kit so eingerichtet, dass er separat automatisch gebaut/veröffentlicht wird, und ihn bei OpenVSX registriert; darauf aufbauend teile ich ein einfaches, Kiro-basiertes Demo-Video.
https://www.youtube.com/watch?v=pIi7CWOPQSA
Als ich früher die C#-Interactive-Funktion verwendet habe, konnte ich keine lokal nicht installierten Pakete nutzen, aber offenbar wurde das inzwischen verbessert.
Hacker-News-Kommentare
npm run <command>.makeodertaskzu verwenden.go run github.com/kardianos/json/cmd/jsondiff@v1.0.1— ziemlich cool.cargogeht so etwas ebenfalls, auch wenn es noch nicht offiziell unterstützt wird: https://rust-lang.github.io/rfcs/3424-cargo-script.htmldotnet runcached die Kompilierung bereits, daher braucht man keine separate Caching-Schicht (zum Deaktivieren--no-build, für den Binärpfad--artifacts-path).dotnetVersion 10 oder 11 ein vollständiger Interpreted Mode eingeführt werden soll. Ich frage mich, ob dieser Modus auch für solche Anwendungsfälle genutzt werden kann: https://github.com/dotnet/runtime/issues/112748*.main.ktsist). Solche Ansätze sind großartig für kleine Skripte oder Prototyping und auch praktisch, um JVM-Funktionen zu nutzen. Für kleine Skripte bleibt Ruby aber weiterhin am bequemsten, besonders wenn man externe Programme ausführt — die Backtick-Syntax ist dafür wirklich praktisch..net10 preview 4-SDK-Image getestet, um Dateien direkt auszuführen, und zunächst funktionierte es nicht. Mitdotnet run <file>lief es aber. Nach einem Update funktionierte es korrekt; die Ursache war, dass die Datei CRLF statt LF als Zeilenende verwendet hatte.#!/usr/local/share/dotnet/dotnet runoder#!/usr/bin/env -S dotnet runverwenden..dump()zu erkunden. Diesesdotnet runkönnte dafür eher eine Ergänzung sein. Früher habe ich an einem Ort gearbeitet, an dem man PowerShell extrem hasste, und dort wurde fast das gesamte Skripting mit LINQPad erledigt — in so einem Umfeld war es brauchbar.dotnet runin VSCode oder Visual Studio im Vergleich zu LINQPad anfühlt. Eine Stärke von LINQPad ist die Visualisierung von Ergebnissen. Wenndotnet runnur Text ausgibt oder viele zusätzliche Plugins braucht, wird es weiter Bedarf für LINQPad geben. Wenn man nur kurz Syntax prüfen will, könntedotnet rundie bessere Wahl sein. Ich selbst probiere gelegentlich verwirrende Syntax auch in LINQPad aus.Ich habe dazu auch zwei praktische Beispiele erstellt und teile sie hier als Antwort. Es handelt sich um Beispielcode für GUI-Apps unter Windows und macOS mit einem MCP-Server und Avalonia. 😊
https://forum.dotnetdev.kr/t/…