代码之家  ›  专栏  ›  技术社区  ›  Xorty

您是否见过合理使用受保护内部访问修饰符的设计?

  •  15
  • Xorty  · 技术社区  · 14 年前

    我没有,但我不认为没有。

    所有读过这篇文章的开发人员可能都知道什么是内部保护,什么时候使用它。我的问题很简单:你是否真的使用过它,或者使用受保护的内部访问修饰符成功地设计了一个项目?如果是,请分享你的知识,并张贴好的样本,在那里我终于可以欣赏这个巧妙的修饰语的巧妙使用。

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

    6 回复  |  直到 14 年前
        1
  •  6
  •   Alex Lo    14 年前

    我相信你可以举出一些例子,但经过五年的发展,我还没有看到一个好的例子。John K的例子很好地说明了修饰符的预期用途,但是我认为导致这种情况的需求是有问题的。在John K的例子中,类在程序集中有“友好的”访问权,一般来说这是个麻烦,因为这些类可能是“询问”,而不是“告知”(编程不礼貌,告知比询问好)。在什么情况下,您有一个有用的可扩展类,朋友可以调用一个方法,但其他人不能?

    另一个用途是测试访问(即您希望它受到保护,但内部的,以便您的程序集级测试可以调用它)。这也是一个麻烦的情况-当你把东西公开为内部测试时,我认为这是依赖注入通常可以处理的设计味道。

        2
  •  5
  •   John K    14 年前

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

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

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

    或者考虑相反的情况:

    • 如果你 只有 使用 受保护的 则同一程序集中的其他类无法访问该成员。

    • 如果你 只有 使用 内部的 则派生类(在其他程序集中)不能重写该方法。

    程序集1.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! 
        }
    }
    

    程序集2.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. 
        }
    }
    
        3
  •  1
  •   Sergey Teplyakov    14 年前

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

    我不喜欢这样的话 从未 “或” 不要 “作为设计指南,但我们至少应该使用” 避免 “建议作为通用设计指南。

        4
  •  0
  •   Jeff Ogata    14 年前

    你真的用过吗

    是的,还有 InternalsVisibleTo 用于单元测试。

        5
  •  0
  •   Richard Anthony Hein    14 年前

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

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

        6
  •  0
  •   Homde    14 年前

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

    我有点担心这个选择会反咬我一口,所以我很想把事情公之于众