I've always been under the assumption that the class generated by Top Level Statements was a hidden, inaccessible class. For example:
System.Console.WriteLine(2);
partial class Program
{
public static string abc = "def";
}
When ran in SharpLab.io using the default branch or the "C# 9: Top-level statements (27 May 2020)" branch, the generated C# will be
// [ ... using and assembly attributes ... ]
internal static class $Program
{
private static void $Main(string[] args)
{
Console.WriteLine(2);
}
}
internal class Program
{
public static string abc = "def";
}
Though it's interesting to note that the default branch emits <Program>$
not $Program
and <Main>$
not $Main
.
However, it's known you can use a partial
class Program
to augment the generated class. Modifying the code to print the field...
System.Console.WriteLine(abc);
partial class Program { public static string abc = "def"; }
... and running again with some particular newer branch "C# Next: File types (5 Jul 2022)" will generate the combined class:
// [ ... using and assembly attributes ... ]
internal class Program
{
public static string abc = "def";
private static void <Main>$(string[] args)
{
Console.WriteLine(abc);
}
}
For the record, I do not know what C# compiler version is used with this branch, I'm assuming some version of C# 10.
However, the default branch or "C# 9: Top-level statements (27 May 2020)" branch will produce a syntax error, where the abc
field cannot be found.
I'm having problems reproducing this issue outside of Sharplab. Creating a .NET 5 / C# 9 (the version that this feature came out in) console application locally compiles and runs:
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>Exe</OutputType> <TargetFramework>net5.0</TargetFramework> <LangVersion>9.0</LangVersion>
</PropertyGroup>
</Project>
System.Console.WriteLine(abc);
partial class Program { public static string abc = "def"; }
// I have SDK 5.0.408 and runtime 5.0.14,15,17 installed, along with others for core 3.1 and .NET 6
Dotnet fiddle will also compile the code, but it only allows me to choose .NET 6, and the C# version is unknown.
Assuming this isn't a bug with Sharplabs, my assumption would be that the class emitted changed for different C# 9 compilers. Sharplabs might be showing the original C# 9 compiler, but my computer might be running a newer version.
The only other evidence I can see is an edit in the dotnet/csharplang git repo that changed the documented emitted class from static class $Program
to partial class Program
. Even though this file is in the "proposal" folder, it does seem to be the same file that is published to Microsoft's documentation, so at some point in the past it was documented that the class name was $Program
.
Why does Sharplab compile the first code block into two classes, and why can't it accept a partial class to augment the entry point class? Was this feature modified after release?