← Back to context

Comment by jug

4 days ago

My favorite .NET 10 feature so far is not within the .NET library itself, but `dotnet tool exec` to run C# files as scripts without a build step. This has been available in F# for a long time via `dotnet fsi`, and for C# also via the third party cs-script tool. It took a surprisingly long time to officially reach the primary .NET language!

I only really wish C# would’ve been directly integrated as an alternative scripting language in PowerShell. You may balk at the idea for causing a ton of cruft for people who don’t need it; ”a whole new scripting language!” But the thing is — PowerShell already builds upon .NET so supporting a new language is a rather small effort (relatively speaking) if it happens to be a .NET language. And C# just feels so much better for me to code in when the scripts grow in size. I’m not sure I’ll ever become friends with the implicit returns. C# has become particularly suitable for scripting with the recent developments in the language: https://learn.microsoft.com/en-us/dotnet/csharp/fundamentals...

"dotnet tool exec" is not that feature; you're thinking of https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-... which they added to "dotnet run". "dotnet run my-cool-thing.cs"

"dotnet tool exec" is so you can run third party command line tools like csharpier that previously required "dotnet tool install" before you could use them. For example, in https://csharpier.com/docs/Installation you can now simply do "dotnet tool exec csharpier". This is like "npx" in the JavaScript world.

  • Ah yes, that's the one I was thinking of. Got confused by this article.

> I only really wish C# would’ve been directly integrated as an alternative scripting language in PowerShell.

You can embed C# in PowerShell scripts, and you have been able to do so for a long time. This webpage has a couple of examples of how this can work:

https://blog.nuvotex.de/run-c-inside-powershell/

  • That's not "embedding C#". That's runtime loading of .NET assemblies, which every .NET language--including PowerShell--can do.

    • It is embedding C#, if it was embedding assemblies it would be embedding compiled code. It's no different from inlining assembly in C.

One of many examples of C# following in F#'s footprints years later. F# deserves a higher profile in the .NET ecosystem.

  • F# has been a third class citizen for a long time... Last I heard the entire f# team was ~10 people. Pretty sure "find references" still doesn't work across c# and f# (if you call a c# method from f# or vise versa). That also means symbol renames don't work correctly.

    • I agree, but somewhat paradoxically, F#’s lack of new features kind of becomes a feature. Have you seen the number of C# features added in the last 5-10 years? It’s crazy

      2 replies →

    • The F# team is smaller than 10 people, always has been.

      ~10 people is the size of the C# and VB language design and compiler team. The IDE side of things for C# and VB is about another 20+ people depending on how you count, although they also build and own infrastructure that (a) the F# team sits atop, and (b) is used by other languages in Visual Studio and is used in VS Code.

      The #1 thing that people always end up surprised by is just how small and effective these teams are.

Now I'm curious if C#/.Net 10 is smart enough to ignore the shebang line. Personally, I've tended to use Deno/TS for my more advanced shell scripting... the main runtime is a single executable that works fine in user context, and dependencies can be loaded/cached at first run.

Of course, with C# as a shell script, you'd likely be limited to just in the box libraries or have to setup a project for sake of running a script, like I've had to do with Node or Python stuff.

  • https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-...

    https://devblogs.microsoft.com/dotnet/announcing-dotnet-run-...

    "dotnet run app.cs" natively supports shebang lines and nugets. The only requirement is to make sure the .net sdk is installed on your computer.

    • I'm guessing, however that using nuget packages means having at least a .csproj file near your .cs file with the packages defined. And downloading the packages, compiling to a space under the .csproj path, similar to a node_modules directory (bin and obj for .Net).

      What I like about Deno, is the packages are downloaded/cached to a shared location not next to your script, and you don't need additional files configured. At least for shell scripts.

      I'm glad shebang works, that will actually help with some process checking I'm wanting to do from CLI without launching my entire services around it.

      1 reply →

I've wanted this for a long time. After reading this link, and the MS release announcement, I still don't understand what a "tool" is, or how you can use `tool exec` to run a single *.cs file. Is there a straight-forward recipe anywhere for doing this targeted at absolute simpletons?