我一直认为Top Level Statements生成的类是一个隐藏的、不可访问的类。例如:
System.Console.WriteLine(2);
partial class Program
{
public static string abc = "def";
}
当在SharpLab.io中使用默认分支或";C#9:Top level statements(2020年5月27日(";分支,生成的C#将是
// [ ... 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";
}
尽管值得注意的是,默认分支发出<Program>$
而不是$Program
,并且<Main>$
而不是$Main
但是,众所周知,您可以使用partial
类Program
来扩充生成的类。正在修改代码以打印字段。。。
System.Console.WriteLine(abc);
partial class Program { public static string abc = "def"; }
并且用某个特定的较新的分支再次运行";C#下一篇:文件类型(2022年7月5日(";将生成组合类:
// [ ... using and assembly attributes ... ]
internal class Program
{
public static string abc = "def";
private static void <Main>$(string[] args)
{
Console.WriteLine(abc);
}
}
记录在案,我不知道这个分支使用的是什么C#编译器版本,我假设是C#10的某个版本。
然而,默认分支或";C#9:Top level statements(2020年5月27日(";分支将产生语法错误,其中找不到abc
字段。
我在Sharplab之外复制这个问题时遇到了问题。创建一个.Net 5/C#9(该功能出现的版本(控制台应用程序本地编译并运行:
<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也会编译代码,但它只允许我选择.Net 6,C#版本未知。
假设这不是Sharplabs的错误,我的假设是,针对不同的C#9编译器,发出的类发生了更改。Sharplabs可能会向显示原始的C#9编译器,但我的计算机可能正在运行更新的版本。
我能看到的唯一其他证据是在dotnet/csharpling git repo中的一个编辑,它将文档化的已发出类从static class $Program
更改为partial class Program
。即使该文件在";提案";文件夹中,它似乎是发布到Microsoft文档中的同一个文件,因此在过去的某个时候,文档中记录了类名为$Program
。
为什么Sharplab将第一个代码块编译成两个类,为什么它不能接受一个分部类来增强入口点类?此功能在发布后是否进行了修改?
这现在反映在顶级语句功能规范中:
类型被命名为"程序";,因此可以通过源代码中的名称引用。它是一个分部类型,因此一个名为";程序";在源代码中也必须声明为分部。
通过2022年6月22日的提交,与之前有所更改:
注意;程序";以及";主";仅用于说明目的,编译器使用的实际名称依赖于实现,类型和方法都不能通过源代码中的名称引用。
我猜测,这一更改是为了支持ASP.NET Core与.NET 6中的新托管模型的集成测试,第一次提到这种可能性是在2021年10月21日。
因此,简而言之,任何现代的.NET 6+编译器都应该生成Program
类,对于早期版本,您不应该依赖于命名(尽管.NET 5现在是EOL,这不是很相关(。