iTranslated by AI

The content below is an AI-generated translation. This is an experimental feature, and may contain errors. View original article

[Experiment] Running 'dotnet run file.cs' with C# 13.0 and earlier

に公開

It's a new C# syntax, but...

https://zenn.dev/inuinu/articles/dotnet-run-file-cs

To allow execution without a project file (*.csproj), the new dotnet run file.cs command in the dotnet CLI introduces a notation called "ignored directives" to C#.

ignored directives
#!/usr/bin/env -S dotnet run
#:sdk      Microsoft.NET.Sdk.Web
#:property TargetFramework net10.0
#:property LangVersion preview
#:package  System.CommandLine 2.0.0-*

Since it is already implemented in the preview[1], it appears to be part of C# 14.0, but it is meaningless (ignored) in terms of C# syntax.

Therefore, it can actually be used in versions prior to C# 13.0.

However, since ignored directives and dotnet run file.cs require .NET SDK support, .NET SDK 10-preview 4 or later is necessary.

How to use dotnet run file.cs with older versions of C#

  • Use .NET 10 SDK or later
  • Write the entry point code using top-level statements
  • Lower the LangVersion via #:property within a compatible range
  • Specify a valid version for TargetFramework via #:property

Use .NET 10 SDK or later

While there is a correspondence between C# language versions and .NET Runtime versions, they do not necessarily have to match perfectly.

For example:

  • Use old C# 8.0 with the latest .NET 9 runtime
  • Use the latest C# 13.0 with old .NET Framework 4.8

Things like this are possible (although there are some limitations).

Since ignored directives and dotnet run file.cs start from .NET SDK 10, we will use that. However, we will lower the language version from 14.

Write the entry point code using top-level statements

The C# code that can be specified with dotnet run file.cs must be written using top-level statements.

Top-level statements were introduced in C# 9.0, which means this can be used with C# 9.0 or later.

Since C# 9.0 was released in 2020, which is quite a while ago, it means you can use slightly older versions of C#.

Lower LangVersion via #:property within a compatible range

Normally, you can specify the C# version by defining LangVersion in the csproj file. To make it work with dotnet run file.cs, specify LangVersion in a directive.

For C# 10.0
#!/usr/bin/env -S dotnet run
#:property LangVersion 10

Console.WriteLine("Hello, World!");

Specify a valid version for TargetFramework via #:property

It appears that the C# program can also be executed on an older version of the .NET runtime by specifying that version.

Running on .NET Framework 4.8.x
#!/usr/bin/env -S dotnet run
#:property LangVersion 9
#:property ImplicitUsings disable
#:property TargetFramework net48

using System;
Console.WriteLine("Hello, World!");

You can also specify runtime versions that are out of support, though a warning will be displayed. Additionally, while you can specify an uninstalled runtime and the build might succeed, it will fail at execution time.

Is it practical?

Not really!

Perhaps only in cases where the SDK is the latest, but you want to maintain an older language version due to project policy...?
(But then again, would such a project even use the new dotnet run file.cs???)

Alternatively, it might be useful for testing how code behaves in an older environment using a simple script. Since dotnet run file.cs allows files to be placed in the same folder without requiring subfolders, it is well-suited for quick testing.

脚注
  1. https://github.com/dotnet/roslyn/blob/main/docs/Language Feature Status.md#working-set-c ↩︎

Discussion