【问题标题】:Why do local functions have the "internal" access modifier?为什么本地函数具有“内部”访问修饰符?
【发布时间】:2021-10-19 17:33:34
【问题描述】:

为什么 Roslyn 编译器使用 internal 访问修饰符(在 IL 中,assembly)而不是 private 生成本地函数?

    private void M()
    {
        bool f = true;
        bool x1() => f;
        static bool x2() => true;
    }
    .method assembly hidebysig static
        bool '<M>g__x1|0_0' (
            valuetype C/'<>c__DisplayClass0_0'& ''
        ) cil managed { ... }

    .method assembly hidebysig static
        bool '<M>g__x2|0_1' () cil managed { ... }

sharplab.io

文档说它应该是私有的:https://docs.microsoft.com/en-us/dotnet/csharp/programming-guide/classes-and-structs/local-functions

本地函数是嵌套在另一个成员中的类型的私有方法。

因为所有本地函数都是私有的,包括访问修饰符,例如 private 关键字,会生成编译器错误 CS0106

【问题讨论】:

  • 旁注:您链接的规范与生成的代码无关 - 该规范是关于在 C# 代码中添加访问修饰符 而您显示的是反编译代码。
  • @AlexeiLevenkov 在第一行显示Local functions are private methods of a type that are nested in another member.。类型的私有方法意味着它应该是私有的。这不是一个规范性文件,但总比没有好。
  • 本地函数的实际规范是here。请注意,它仍然显示“TODO: WRITE SPEC”(大写),并且没有包含有关可访问性的详细信息。规范的后续版本完善了您可以使用本地函数执行的操作,但在这一点上根本没有改进。对于不是“草稿”的规范来说,C# 早就应该过期了,即使构建新功能比将它们整合到一个正式规范中要性感得多,即使(非正式)语言描述通常做​​得不错。
  • @OwnageIsMagic "2. Reflection" 无论如何,反射只是规避了整个类型和访问安全特性,所以指出这有点无关紧要。
  • @Flater 修改了类的非私有接口,可以干扰RPC(remoting)等反射的各种合法使用,而InternalsVisibleToAttribute变成了 > 界面。

标签: c#


【解决方案1】:

看起来像代码重用工件。 Roslyn 可能使用相同的代码来处理本地函数和 lambda,但在不同的类中注入方法定义。

在 lambda 的情况下,它会将 lambda 主体注入到生成的闭包 (DisplayClass) 类中,并且它应该是内部的,以便从调用函数中引用。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2011-04-12
    • 1970-01-01
    • 2011-04-18
    • 1970-01-01
    • 2020-03-10
    • 2015-11-26
    相关资源
    最近更新 更多