什么情况下生成的Top Level Statement类会是$Program?

2024-01-13

我一直假设顶级语句生成的类是一个隐藏的、不可访问的类。例如:

System.Console.WriteLine(2);

partial class Program
{
    public static string abc = "def";
}

当使用 SharpLab.io 运行时默认分支 https://sharplab.io/#v2:CYLg1APgAgjAdLAnACgEwEoDcBYAUHgBwEMAnAFwEsiAbAAilXpgHY8BvPWr+gZiYDYmABlpEARgGNaAXloAiYAFMAZnJy4AvkA= or the “C# 9:顶级语句(2020 年 5 月 27 日)”分支 https://sharplab.io/#v2:EYLgZgpghgLgrgJwgZwLQGUCWBbADgGwgAUEB7AcwSm2QBoATEAagB8ABARgDpOBOACgBMASgDcAWABQU3FAQxMUfAAI2g1RwDsUgN5TlB1QGYNANg0AGZVGABjZQF5lAInoQwziZIC+QA==,生成的 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";
}

Though it's interesting to note that the default branch emits <Program>$ not $Program and <Main>$ not $Main.

然而,它被称为 https://stackoverflow.com/a/71058076/1043380你可以使用partial class Program来扩充生成的类。修改代码以打印该字段...

System.Console.WriteLine(abc);
partial class Program { public static string abc = "def"; }

...并再次运行一些特别的较新的分支“C# 下一篇:文件类型(2022 年 7 月 5 日)” https://sharplab.io/#v2:EYLgZgpghgLgrgJwgZwLRgJYBsKpgTwAcUAaAExAGoAfAAQEYA6BgTgAopgBjASgG4AsAChCUBDAxQsAAloAmWfQDs0gN6yAzIoBsigAzTOXaQF5pAIjIQw5vtIC+woA将生成组合类:

// [ ... 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.

但是,那默认分支 https://sharplab.io/#v2:CYLg1APgAgjAdLAnACgIYCMDGBKA3AWACgAHVAJwBcBLVAGwAIoAmRmAdnoG9GBmVgNlYAGehkz0AvPQBEwAKYAzabnoBfIkA=== or “C# 9:顶级语句(2020 年 5 月 27 日)”分支 https://sharplab.io/#v2:EYLgZgpghgLgrgJwgZwLQGUCWBbADgGwgAUEB7AcwSm2QBoATEAagB8ABARgDpOBOACijAAxgEoA3AFgAULigIYmKPgAEbAExqOAdhUBvNQGYtANi0AGFUOEqAvCoBE9CGAfiVAXxlA=将产生语法错误,其中abc找不到字段。

我在 Sharplab 之外重现此问题时遇到问题。创建.Net 5 / C# 9(此功能的版本出来了 https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-9.0/top-level-statements) 控制台应用程序在本地编译并运行:

<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

点网小提琴 https://dotnetfiddle.net/nFKPbM也会编译代码,但它只允许我选择.Net 6,C#版本未知。

假设这不是 Sharplabs 的错误,我的假设是发出的类针对不同的 C# 9 编译器发生了变化。 Sharplabs 可能会展示原本的C# 9 编译器,但我的计算机可能正在运行较新的版本。

我能看到的唯一其他证据是对dotnet/csharplang git 存储库 https://github.com/dotnet/csharplang/commit/d7c3bef81a34aaa417cd47675fdd2e73ef092d27#diff-a18fd8818ea93281948d26740ec76d542595a3bc52c075075937d8a12c175013L150-R152改变了记录的发出类static class $Program to partial class Program。尽管该文件位于“proposal”文件夹中,但它似乎与“proposal”文件夹中的文件相同。发布到微软的文档 https://web.archive.org/web/20220411230010/https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-9.0/top-level-statements,所以在过去的某个时刻,有记录表明类名是$Program.

为什么 Sharplab 将第一个代码块编译为两个类,为什么它不能接受部分类来扩充入口点类?这个功能发布后有修改吗?


这现在反映在顶级声明 https://learn.microsoft.com/en-us/dotnet/csharp/language-reference/proposals/csharp-9.0/top-level-statements#semantics功能规格:

该类型被命名为“Program”,因此可以通过源代码中的名称进行引用。它是一个部分类型,因此源代码中名为“Program”的类型也必须声明为部分类型。

这是从previous https://github.com/dotnet/csharplang/blob/1dbcfb485ce782bb4cb6e7bbbdeb264bcb9641b7/proposals/csharp-9.0/top-level-statements.md via 这次提交 https://github.com/dotnet/csharplang/commit/d7c3bef81a34aaa417cd47675fdd2e73ef092d272022 年 6 月 22 日:

请注意,名称“Program”和“Main”仅用于说明目的,编译器使用的实际名称取决于实现,并且类型和方法都不能通过源代码中的名称引用.

我猜这个改变是为了支持ASP.NET Core 中的集成测试 https://learn.microsoft.com/en-us/aspnet/core/migration/50-to-60-samples?view=aspnetcore-6.0#aspnet-core-6-9.NET 6 中的新托管模型以及首次提及这种可能性的日期2021 年 10 月 21 日 https://github.com/dotnet/AspNetCore.Docs/blob/aafdca64fc73938c1b9878018e77d6ecca91bcce/aspnetcore/migration/50-to-60-samples.md#project-file-csproj.

简而言之 - 任何现代 .NET 6+ 编译器都应该生成Program类,对于早期版本,您不应该依赖命名(尽管 .NET 5 现在已经 EOL,这不是很相关)。

本文内容由网友自发贡献,版权归原作者所有,本站不承担相应法律责任。如您发现有涉嫌抄袭侵权的内容,请联系:hwhale#tublm.com(使用前将#替换为@)

什么情况下生成的Top Level Statement类会是$Program? 的相关文章

  • 为 DocumentDb 设置自定义 json 转换器

    我正在使用类型化 DocumentQuery 从 Azure DocumentDb 集合中读取文档 from f in client CreateDocumentQuery
  • 无法在 QGLWidget 中设置所需的 OpenGL 版本

    我正在尝试在 Qt 4 8 2 中使用 QGLWidget 我注意到 QGLWidget 创建的默认上下文不显示 OpenGL 3 1 以上的任何输出 Qt wiki 有一个教程 http qt project org wiki How t
  • copy_from_user() 错误:目标大小太小

    我正在为内核模块编写 ioctl 处理程序 我想从用户空间复制数据 当我编译禁用优化的代码时 O0 gflags 编译器返回以下错误 include linux thread info h 136 17 error call to bad
  • 无法在 CUDA 中找到 1 到 100 数字的简单和?

    我正在研究使用 CUDA 的图像处理算法 在我的算法中 我想使用 CUDA 内核找到图像所有像素的总和 所以我在cuda中制作了内核方法 来测量16位灰度图像的所有像素的总和 但我得到了错误的答案 所以我在cuda中编写了一个简单的程序来查
  • 来自 double 的 static_cast 可以优化分配给 double 吗?

    我偶然发现了一个我认为不必要的功能 并且通常让我感到害怕 float coerceToFloat double x volatile float y static cast
  • CMake(Ninja 后端)使用 /MT 编译

    我有一个类似的问题CMake 使用 MT 而不是 MD 进行编译 https stackoverflow com questions 14172856 cmake compile with mt instead of md但有一些差异 我正
  • 如何在 C++ 中为指针“this”赋值

    在函数中 如何分配this一个新的价值 您可以分配对象this点于 this XY 但你不能分配直接值this this XY Error Expression is not assignable
  • 从结构调用 C++ 成员函数指针

    我找到了有关调用 C 成员函数指针和调用结构中的指针的信息 但我需要调用结构内部存在的成员函数指针 但我无法获得正确的语法 我在类 MyClass 的方法中有以下代码片段 void MyClass run struct int MyClas
  • 获取列表框中视图中的项目

    我有一个 ListBox 其属性 VirtualizingStackPanel VirtualizationMode 设置为 回收 我正在绑定一个自定义集合 实现IList and IList
  • 加载 QPixmap 数据的更好方法

    更好的方法来做到这一点 没有QImage QImage image width height QImage Format RGB888 memcpy image bits m frameRGB gt data 0 height width
  • 大量互斥体对性能的影响

    假设我有一个包含 1 000 000 个元素的数组 以及多个工作线程 每个线程都操作该数组中的数据 工作线程可能会使用新数据更新已填充的元素 但每个操作仅限于单个数组元素 并且独立于任何其他元素的值 使用单个互斥锁来保护整个数组显然会导致高
  • 从图像创建半透明光标

    是否可以从图像创建光标并使其半透明 我目前正在拍摄自定义图像并覆盖鼠标光标图像 如果我可以将其设为半透明 那就太好了 但不是必需的 销售人员喜欢闪亮的 目前正在做这样的事情 Image cursorImage customImage Get
  • 如何在 C++ 中正确使用 cin.fail()

    我正在编写一个程序 从用户那里获取整数输入cin gt gt iUserSel 如果用户输入一个字母 程序就会进入无限循环 我试图用下面的代码来阻止这种情况 但程序进入无限循环并打印出 错误 输入 我该如何修复我的程序 cin gt gt
  • 更改私有模块片段是否会导致模块重新编译?

    On 此页面有关 C 20 模块功能 https www modernescpp com index php c 20 modules private module fragment and header units 我发现了这样的说法 借
  • 将 AutomationID 与 ListView 结合使用

    我正在尝试将 AutomationId 附加到列表视图中的项目 理想情况下 将项目名称绑定到显示的项目
  • 为什么存在系统调用

    我一直在阅读有关系统调用及其在 Linux 中如何工作的内容 我还有更多的阅读要做 但我读过的一件事都没有回答 那就是 为什么我们需要系统调用 我知道系统调用是用户空间程序要求内核执行某些操作的请求 但我的问题基本上是 为什么用户空间程序本
  • 如何配置 qt Creator 以显示 C++ 代码而不是反汇编程序?

    昨天我做了很多事情 比如更新 GCC Clang 和重新安装 Qt Creator 今天 在逐步调试我的代码时 调试器显示的是反汇编代码 而不是我编写的 C 代码 紧迫F10 or F11 调试器正在进入汇编代码而不是 cpp nor h我
  • Adobe Illustrator 中的折线简化如何工作?

    我正在开发一个记录笔划的应用程序 您可以使用定点设备来绘制笔划 在上图中 我绘制了一个笔划 其中包含 453 个数据点 我的目标是大幅减少数据点的数量 同时仍然保持原始笔画的形状 对于那些感兴趣的人 上图笔画的坐标可以作为GitHub 上的
  • NHibernate:无状态会话错误消息无法获取代理

    我正在使用 nHibernate 无状态会话来获取对象 更新一个属性并将对象保存回数据库 我不断收到错误消息 无状态会话无法获取代理 我在其他地方有类似的代码 所以我不明白为什么这不起作用 有谁知道问题可能是什么 我正在尝试更新Screen
  • 如何使用 Microsoft Graph API 更新 MailboxSettings

    我想从不同的日历更新邮箱设置 如何构建可以通过 Microsoft Graph 更新 MailboxSetting 的请求 这是我的代码示例 但有例外 代码示例 User obj GraphServiceClient Users roomC

随机推荐