【问题标题】:What is the meaning of the planned "private protected" C# access modifier?计划中的“私人保护”C# 访问修饰符是什么意思?
【发布时间】:2014-05-16 09:05:04
【问题描述】:

作为 GitHub 上 Roslyn 文档的一部分,有一个名为 Language feature implementation status 的页面,其中包含 C# 和 VB 的计划语言功能。

我无法理解的一个功能是private protected 访问修饰符:

private protected string GetId() { … } 

还有一个C# Language Design Notes的页面,里面解释了很多新功能,但没有这个。

Eric Lippert 在comment 中说:

您的错误在于将修饰符视为增加限制。修饰符实际上总是减少限制。请记住,默认情况下,事情是“私人的”;只有添加修饰符才能减少它们的限制。

private protected是什么意思?我什么时候可以使用它?

【问题讨论】:

  • 注意VB language design notes下面有关于它的信息。
  • 它是到 MethodAttributes.FamANDAssem 的映射。 C# 有一个奇怪的 internal 映射,它使用 (Private|FamANDAssem)。并且 internal protected 映射到 (Private|Family)。 CLR 属性很奇怪。
  • 这个提议的功能会使我的评论不正确。
  • C# 设计团队为此功能发布了survey with suggested alternative syntax。其中一些很有趣,例如protected & internalassembly protectedproternal(我希望其中一些是笑话)。还有Discussion thread 有一些很好的见解。
  • 功能现在在语言功能实施状态下被标记为撤回!我个人喜欢这个访问级别的想法,我认为它是一个有用的功能。我想根据类设计使用受保护来保留我的代码,但我不希望其他人编写可以访问这些成员的 hacky sublasses。 IMO 最好的解决方案是如果我们可以写 protected | internalprotected & internal

标签: c# access-modifiers c#-6.0 c#-7.2


【解决方案1】:

这只是一个猜测,但从名称上您可能会猜到它是protected 的更受限制的版本,(如果您愿意,也可以是private 的更宽松的版本)。它的唯一合理变体是将protected 行为限制为汇编。

可能的用法:那么您希望将protected 用于内部实现,但不用于外部使用(并且您不想密封类)。

附:它一直存在于CLR, but not in C#。它是protected internal 的组合,引用:

CLR 还支持“Family and assembly”访问类型。这意味着该方法可以从声明类型、嵌套类型和派生类型中访问,但前提是它们在同一个程序集中声明。好吧,显然 C# 团队并不认为这是一个非常有用的功能,因此该语言不支持它。

【讨论】:

  • CLR 评论 +1 - 这些天我在 C# 上花了很多时间,而在其他 .NET 语言上花的时间很少,以至于我有时会忘记它们不是一回事。
  • @DarrelHoffman 感谢您的关注!我在这里有点混淆了我的想法)
【解决方案2】:

“可能”仅对同一程序集中的子类可见。这使得它比protected 有点受限。

【讨论】:

    【解决方案3】:

    根据 De Bill Evjen 和 Jay Glynn 的“Professional C# 2008”,第 1699 页:

    私有保护 - “仅在当前程序集中派生类型”

    C++/CLI 也有类似的特性——Define and Consume Classes and Structs (C++/CLI) > Member visibility:

    private protected - 或 - protected private - 成员在程序集内受到保护,但在程序集外是私有的。

    【讨论】:

    • 所以它是“受保护的内部”而不是“受保护的内部”?
    • 现在是否可以让派生类可以访问的成员接受或返回 internal 类型的内容,而无需将成员本身暴露给程序集中的所有内容?
    • 谢谢!我没想到。实际上,我有一些案例我会使用该修饰符,然后转而使用 internal
    • 这个提议/特性的存在似乎表明internal可见性(与定义类的位置有关)实际上与public/protected/private可见性(相关继承),也许internal 应该是它自己的修饰符,与public/protected/private 分开。
    【解决方案4】:

    这只是为了提供不同可访问性级别的图表(使用http://ashitani.jp/gv/ 制作)(图像不适合 cmets)。

    每个箭头表示“比限制更严格”。

    CLR 名称为 PrivateFamilyANDAssemblyAssemblyFamilyFamilyORAssemblyPublic


    很久以后的编辑:事实证明,这个不错的新访问级别(名字很糟糕)没有最终包含在 C# 6.0 中。它仅受 C# 7.2 支持(我看到您更新了您的问题“标签”)。

    【讨论】:

    • 可能只是我,但箭头似乎朝着“比限制更少”的方向发展。
    • @acarlon 是的,所以图中的a → b 表示“ab 更具限制性”,因此您可以将箭头“阅读”为“比@更具限制性”(即是我试图解释的),所以箭头指向限制最少的“方向”。顺便说一下,箭头的相反约定可能同样好,但我必须选择一种约定。
    【解决方案5】:

    这里是维恩图中的所有访问修饰符,从更多限制到更混杂:

    private:

    private protected: - added in C# 7.2

    internal:

    protected:

    protected internal:

    public:

    【讨论】:

    • 源图片:Access Modifiers.pdn。我使用了恰当命名的Paint.Net
    • 我的 (C#) 生活中这些图表在哪里?他们很棒 - 谢谢!
    【解决方案6】:

    请参阅spec 了解“私人保护”功能:

    private protected 的直观含义是“可在此程序集中通过派生自包含类的类型访问”。

    【讨论】:

      猜你喜欢
      • 2012-01-28
      • 1970-01-01
      • 2017-05-16
      • 2016-04-03
      • 2012-05-14
      • 1970-01-01
      • 2016-12-11
      • 1970-01-01
      相关资源
      最近更新 更多