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

我没有,但我不说没有。

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

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

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

另一个用途是测试访问(IE希望它受到保护,但内部因此你的程序集级别测试可以调用它)。 这也是一个麻烦的情况 – 当你将内容暴露在内部进行测试时,我认为这是dependency injection通常可以处理的设计气味。

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

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

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

或者考虑相反的情况:

  • 如果您使用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. } } 

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

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

你真的用过吗?

是的,与InternalsVisibleTo一起进行unit testing。

对于那些想要inheritance你的类型的人来说,这只是一个意思,因为他们并不像你那样为同一家公司工作。 😉

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

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

我有点担心选择会回来咬我,不过如此,我很想把事情公之于众