【问题标题】:Have you ever seen design with reasonable usage of protected internal access modifier?你见过合理使用受保护的内部访问修饰符的设计吗?
【发布时间】:2011-04-22 00:22:58
【问题描述】:

我没有,但我不是说没有。

阅读本文的所有 C# 开发人员可能都知道什么是内部保护的以及何时使用它。我的问题很简单:您是否真的使用过它或使用受保护的内部访问修饰符成功设计过项目?如果是,请分享您的知识并发布漂亮的示例,我终于可以欣赏到这个棘手的修饰符的巧妙用法。

// 我相信这不是主观的,我实际上是在寻找答案;-)

【问题讨论】:

  • .Net 框架使用了很多内部结构:)
  • 感谢您提出这个问题。并为其中的“合理”词 +1。

标签: c# access-modifiers


【解决方案1】:

我相信你能想到例子,但是在五年的 C# 开发中,我还没有看到一个好的案例。 John K 的示例很好地说明了修饰符的预期用途,但是我认为导致这种情况的要求是有问题的。在 John K 的示例中,该类在程序集中具有“友好”访问权限,通常这很麻烦,因为这些类可能是“询问”,而不是“告诉”(编程不礼貌,最好告诉而不是询问)。在什么情况下,您有一个有用的可扩展类,Friends 可以调用方法,但其他人不能?

另一个用途是测试访问(您希望它受到保护,但在内部,因此您的组装级测试可以调用它)。这也是一个麻烦的情况 - 当您将事物公开为内部测试时,我认为这是依赖注入通常可以处理的设计气味。

【讨论】:

  • 我不知何故觉得为单元测试打开“后门”可能很舒服,但它有点伤害设计:-/
  • 关于打开内部进行测试,这里值得注意的是,微软提供了一个属性,允许internal通过InternalsVisibleToAttribute 暴露给另一个程序集bit.ly/9UkCZe
【解决方案2】:

是的,在继承情况下,只要允许同一程序集(内部)中的其他类以“友好”/受信任的方式直接访问虚拟或抽象类成员,但该成员也可以被派生覆盖外部程序集中的类(通过受保护)。

此组合修饰符允许程序集完全信任自己的内容和内部使用(这不是异常),同时将其中一些成员暴露给其他程序集的正常继承派生模型。

没有一个修饰符可以做到这一点。

或者考虑相反的情况:

  • 如果您使用protected,则同一程序集中的其他类无法访问该成员。

  • 如果您使用内部,则派生类(在其他程序集中)无法覆盖该方法。

Assembly1.dll

// ------ Assembly file 1 .dll --------

// Allow my friends (internal) and derived classes (protected) to do this. 
public class A {
    internal protected virtual void YoBusiness() {
        //do something
    }
}


class B { // not a derived class - just composites an instance of A
    public B() {
        A a = new A();
        a.YoBusiness(); // Thanks friend for the access! 
    }
}

Assembly2.dll

// ------ Assembly file 2 .dll --------

class C : A {  // derived across assemblies
    protected override void YoBusiness() {
        // Hey thanks other guy, I can provide a new implementation. 
    }
}

【讨论】:

  • 这描述了protected internal 是什么,但没有描述它的实际用途。
  • 我没有描述一个特定的项目本身,而是描述了一个场景(它的一般用途,同样有用),除了它是什么。代码示例提供了该场景的证明,因此很容易在任何项目中发现。
【解决方案3】:

所有protectedinternal 成员都会增加复杂性、耦合性并因此降低抽象完整性。您可能会考虑实现一些内部或受保护的方法,但通常使用内部或受保护的字段是非常糟糕的主意。受保护/内部字段“打开”您的抽象实现,适用于广泛的类和高度复杂的未来修改。

我不喜欢“从不”或“”这样的词作为设计指南,但我们绝对应该至少使用“avoid" 建议作为通用设计指南。

【讨论】:

    【解决方案4】:

    你真的用过吗

    是的,以及用于单元测试的 InternalsVisibleTo

    【讨论】:

      【解决方案5】:

      这只是对那些想继承你的类型的人刻薄,因为他们和你不在同一家公司工作。 ;-)

      不过,说真的,这个问题仅适用于内部......我们知道您为什么要使用受保护的,对吧?那么,为什么是内部?可能只有当您知道您的类型访问某些仅在同一程序集中可用的资源时。无论是实际资源,还是您不想与世界分享的其他类型。

      【讨论】:

        【解决方案6】:

        实际上,我今天必须在我的职业生涯中第一次使用它!我有一个带有基类的插件架构,插件仅通过外观类公开。限制插件只能通过 faqade 调用的唯一方法是使其受内部保护,因为覆盖它的插件位于其他程序集中,而 faqade 层与基类位于相同

        我有点担心选择会回来以某种方式咬我,所以我很想把事情公开

        【讨论】:

          猜你喜欢
          • 2023-03-14
          • 2013-03-05
          • 1970-01-01
          • 2014-12-29
          • 2013-04-03
          • 2019-05-07
          • 2015-11-27
          相关资源
          最近更新 更多