c# - C++ 和 C# 中的复合模式 - protected 虚拟方法

标签 c# c++ oop design-patterns composite

如何在“Component”类中添加 protected 虚拟方法,以便可以从“Composite”中调用它?

作为一个具体的例子,请看下面的代码,请告诉我如何避免DxCompositeShape.ComputeSize中的编译器错误。

abstract class DxShape // this is the Component
{
    public abstract void Paint();
    protected abstract void ComputeSize();
}

class DxCompositeShape : DxShape // this is the Composite
{
    public readonly IList<DxShape> Shapes = new List<DxShape>();

    public override void Paint()
    {
        this.ComputeSize();
    }

    protected override void ComputeSize()
    {
        foreach (DxShape sh in Shapes)
        {
            sh.ComputeSize(); // compiler error CS1540
        }
        // and some other logic here
    }
}

编辑:我修改了我的示例,因此我用 ComputeSize 而不是 Init (人们认为 Init 始终可以在构造函数中调用)。

最佳答案

你不能。仅当编译器可以看到相关对象与当前对象的类型相同时,才能调用不同对象的 protected 成员。基本上,“ protected ”意味着“派生类可以在自己的类中使用此成员。

这里的根本问题是,您希望某些特权类(“复合体”)能够调用基类声明的外部类(“组件”)的方法,该方法仅供派生类在其自己的实现中使用.

如果所有组合都在同一个包中,您可能希望将 Init 设为内部。或者,可以创建所有组合都继承的组件的子类,并让该特定类有权在所有组件上调用 Init 。在 C++ 中,您可以通过友元声明来完成这样的事情。在 C# 中,谨慎使用内部访问可能是正确的解决方案。

关于c# - C++ 和 C# 中的复合模式 - protected 虚拟方法,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/18103693/

相关文章:

C# 生产质量线程安全内存 LRU 缓存过期?

c# - 在 foreach 或 GetEnumerator() 中产生 yield ?

c++ - 表达式 'i < 0' 始终为假

c++ - 我应该让我的功能尽可能通用吗?

C# 自动完成文本框点击事件

c# - 为什么我需要在 params 前加上 out 或 ref?

c++ - 模板类型定义的数组初始化

php - 如何确保我们在属性上使用 __invoke 而不是在主对象上使用 __call?

c++ - 是否可以从抽象类构造函数中调用虚方法?

php - 使用不兼容的函数实现接口(interface)和错误