We have some exciting news to announce - dotnet-script is now supporting .NET Core 3.0.
We released the new version 0.50.0, with .NET Core 3.0 support already on September 25th, two days after .NET Core 3.0 went RTM, but kept quiet about it. The reason was that a large part of the scripting experience is the tooling in OmniSharp and the C# Extension for VS Code, and that had to be updated accordingly too.
.NET Core 3.0 support π
While there are still multiple ways of acquiring dotnet-script, the recommended way is to use the global tool installation process:
~/ dotnet tool install -g dotnet-script
You can invoke the tool using the following command: dotnet-script
Tool 'dotnet-script' (version '0.50.1') was successfully installed.
or to update an existing installation:
~/ dotnet tool update -g dotnet-script
Tool 'dotnet-script' was successfully updated from version '0.29.1' to version '0.50.1'.
dotnet-script is now cross compiled into .NET Core 2.1 and .NET Core 3.0, and depending on your active dotnet SDK, the relevant version of the tool will be used on your machine. Fundamentally what changes in dotnet-script is that it is faster now, you can use netcoreapp3.0 and netstandard2.1 dependencies, as well as C# 8.0.
It might also seem like there wouldn’t be that much to do to support .NET Core 3.0 - after all, from the user perspective things are not that much different between 2.1 and 3.0. The reality however is much different - pretty much all of the SDK-related machinery to make a script work that we rely on when it comes to discovering the runtime dependencies (to excute the script) and compilation dependencies (to provide intellisense and tooling) have changed completely. We needed to rewrite lots of dotnet-script internals from scratch. And I also keep using “we” here, but it has to be said that the majority of work has been done by Bernhard without whom there wouldn’t be this release at all!
Tooling π
The tooling changes have now been merged and released in version 1.34.5 of OmniSharp. This build of OmniSharp was then integrated into the 1.21.5 version of the C# Extension for VS Code.
However, at the time of writing, that C# Extension version, is not yet available in the marketplace. You can, nevertheless, install it from this link by using the install from VSIX feature. You could also use the “omnisharp.path”: “1.34.6-beta.20” setting in VS Code to force the extension to pull the latest available OmniSharp build.
I do expect the 1.21.5 version to be released into the marketplace this week and then it will just automatically show up in the extension updates.
C# 8.0 π
dotnet-script 0.50.x provides support for C# 8.0. When using the dotnet-script variant on top of .NET Core 3.0 (with .NET Core 3.0 SDK) you can use language features that rely on runtime features such as for example async enumerable or async disposable. In the case of running against .NET Core 2.1, you can still use language features of C# 8.0 as long as they don’t have runtime coupling, such as for example null-coalescing assignment.
In addition to that, nullable reference types are special cased in scripting. After all, there there is no csproj project file, which is normally used to control them and define the warning-vs-error behavior. What we have done in scripting, is that you need to enable nullable reference types using the inline #nullable directive (same as in regular C#, where you can use that if you don’t want to use the project file) and then all the nullable related warnings will be treated as errors automatically.
For example consider the following script:
string foo = null;
Console.WriteLine(foo.Length);
This obviously fails with the null reference exception.
However, if you use #nullable enable in a CSX script, to enable the compiler’s nullability analysis:
#nullable enable
string foo = null;
Console.WriteLine(foo.Length);
the script will no longer execute, instead it will fail with warnings (promoted to errors, as mentioned):
main.csx(2,14): error CS8625: Cannot convert null literal to non-nullable reference type.
main.csx(3,19): error CS8602: Dereference of a possibly null reference.
Another example of a useful script language feature could be ranges. With the range syntax, it’s much easier to operate on collections. Consider the following example:
var letters = new[] { "a", "b", "c", "d", "e", "f" };
Print(letters[..3]);
void Print(string[] letters)
{
foreach (var l in letters) Console.WriteLine(l);
}
This script prints:
a
b
c
For more on C# 8.0 language features, please refer to a great article on what’s new in C# 8.0.
And if you encounter any issues with dotnet-script on .NET Core 3.0 please make sure to open an issue!