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

发布于 2024-09-26 17:36:52 字数 187 浏览 7 评论 0原文

我没有,但我不说没有。

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

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

I haven't, but I don't say there isn't one.

All of the C# developers who read this probably do know what is protected internal and when to use it. My question is simple : did you actually ever use it or worked on a successfully designed project using protected internal access modifier? If yes, please share your knowledge and post nice sample, where I can finally appreciate clever usage of this tricky modifier.

// I believe this isn't subjective, I am actually seeking for an answer ;-)

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(6

扭转时空 2024-10-03 17:36:52

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

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

I'm sure you can think of examples, but in five years of C# development, I've not seen a good case for it. John K's example illustrates the intended use of the modifier nicely, however I think the requirements that lead to this situation are problematic. In John K's example, the class has "friendly" access within the assembly, and in general this is trouble, because those classes are probably "asking", not "telling" (programming is not polite, it is better to tell than to ask). In what case do you have a useful extendable class that Friends can call a method on but others cannot?

Another use would be for testing access (IE you want it to be protected, but internal so your assembly level tests can call it). This is a trouble situation too - when you expose things as internal for testing I think it is a design smell that dependency injection can usually handle.

蓝眼泪 2024-10-03 17:36:52

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

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

没有任何一个修改器可以做到这一点。

或者考虑相反的情况:

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

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

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

Yes, in an inheritance situation whenever a virtual or abstract class member was allowed to be directly accessed by other classes inside the same assembly (internal) in a "friendly"/trusted manner, but also that member could be overriden by derived classes in external assemblies (via protected).

This combo modifier allows the assembly to fully trust its own contents and internal usage (which is not abnormal), while exposing some of those members to the normal inheritance derivation model for other assemblies.

No single modifier can do this.

Or consider the reverse situations:

  • if you only use protected then other classes inside the same assembly cannot access that member.

  • if you only use internal then derived classes (in other assemblies) cannot override that method.

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. 
    }
}
潦草背影 2024-10-03 17:36:52

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

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

All protected or internal members increase complexity, coupling and therefore reducing abstractions integrity. You may thinking implementing some methods internal or protected, but using internal or protected fields in general is very bad idea. Protected/internal fields "open" your abstractions implementation for wide range of classes and highly complicate future modifications.

I don't like words like "never" or "do not" as design guidelines, but we definitely should use at least "avoid" suggestion as common design guideline.

上课铃就是安魂曲 2024-10-03 17:36:52

你真的用过吗

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

did you actually ever use it

Yes, along with InternalsVisibleTo for unit testing.

烟花易冷人易散 2024-10-03 17:36:52

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

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

It's just to be mean to people who want to inherit from your type, because they don't work for the same company as you. ;-)

Seriously, though, the question applies to internal alone ... we know why you'd use protected, right? So, why internal? Probably only when you know that your type accesses some resources that are only available within the same assembly. Whether that is an actual resource, or another type that you don't want to share with the world.

为你拒绝所有暧昧 2024-10-03 17:36:52

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

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

I actually had to use it for the first time in my career today! I have an plugin architecture with baseclases and the plugins are exposed only through a facade class. The only way to restrict so that the plugin is callable only through the faqade is to make it protected internal since the plugins that override it lies in other assemblies while the faqade layer lies in the same as the base class

I'm a bit worried that the choice will come back to bite me somehow though so I'm tempted to just make things public

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文