C# 是否正在寻找其他方法来隐藏子类中的抽象继承方法?

C# 是否正在寻找其他方法来隐藏子类中的抽象继承方法?,c#,oop,inheritance,overriding,abstract,C#,Oop,Inheritance,Overriding,Abstract,我希望继承的方法Invoke()对最后一个子类ConcreteExecutablePlugin隐藏 整体情况: public abstract class PluginBase { public abstract void Invoke(IDictionary parameters); } public abstract class JobPlugin : PluginBase { protected void CheckParameter(){//....} p

我希望继承的方法
Invoke()
对最后一个子类
ConcreteExecutablePlugin
隐藏

整体情况:

public abstract class PluginBase
{
     public abstract void Invoke(IDictionary parameters);
}

public abstract class JobPlugin : PluginBase
{
     protected void CheckParameter(){//....}
     public bool IsActive(){//....}
}

public class ConcreteJobPlugin : JobPlugin
{
      public override void Invoke(IDictionary parameters){//...}   
}

public abstract class ExecutableJobPlugin : JobPlugin 
{
     protected abstract void Initialize(IDictionary parameters);
     public sealed override void Invoke(IDictionary parameters)
     {
          //final realization of Invoke() method
     }
}

public class ConcreteExecutablePlugin : ExecutableJobPlugin
{
     //here i want method Invoke() has been already hiden
     //!!!OR use base.Invoke() better?

     protected override void Initialize(IDictionary parameters)
     {
           //concrete plugin initialization
     }
}
我只找到了一个解决办法。现在,我用的是密封的。你觉得这个解决方案怎么样


您知道隐藏抽象继承方法的其他方法吗?

在派生类中隐藏公共方法是不可能的。
public
的全部要点是,该方法可以在基类及其任何子类中访问


您可以尝试使用受保护的
,然后在派生插件中简单地使用
public
方法,如
初始化
,或者您可以尝试使用
内部
(尽管这可能不是最好的方法)。

Re:Visibility

公共方法向设计意图发出信号,表明它对所有人都可见-如果这不是设计意图,则相应地更改方法的可见性,例如
受保护的
(但显然任何子类都有访问权限),或者如果允许使用
调用的所有类都在同一程序集中,然后可以声明
Invoke
受保护的内部摘要

Re:Sealed

根据Lasse的观点,
sealed override
方法将在继承期间中断多态的
虚拟/override
链,但它仍然不能改变基本方法是公共的这一事实。但是,将
sealed
应用于一个类将阻止其他类继承它,从而限制对所有受保护方法的访问

解决方案

我认为潜在的问题与过度使用继承有关-似乎您希望继承功能以获得重用,但同时需要将链中某个点的访问限制为“不可信”子类。除了让方法
internal
+将所有“可靠”的子类移动到基类程序集中之外,在使用完整的子类链时,您几乎没有控制权

我相信,通过接口分离您的层次结构,并应用的原则,将更好地实现您的目标。事实上,这看起来是一种选择

您还可以通过将“最后一个可信”子类(
ExecutableJobPlugin
)设置为
sealed
*)来设置“可信”边界

示例:

// Expose  just what is visible to your final Subclass on the interface
public interface IExecutableJobPlugin
{
    bool IsActive { get; set; }
    void CheckParameter();
    void Initialize(IDictionary parameters);
}

// Sealed will prevent other classes from inheriting this class.
public sealed class ExecutableJobPlugin : JobPlugin, IExecutableJobPlugin 
{
    // Default implementation. NB, not abstract
    public void Initialize(IDictionary parameters) {}

    // This isn't visible on the interface
    protected override sealed void Invoke(IDictionary parameters)
    {
        //final realization of Invoke() method
    }
}

public class ConcreteExecutablePlugin : IExecutableJobPlugin
{
    // Compose a decoupled IExecutableJobPlugin instead of direct inheritance
    private readonly IExecutableJobPlugin _wrappedJobPlugin;
    public ConcreteExecutablePlugin(IExecutableJobPlugin wrapped)
    {
        _wrappedJobPlugin = wrapped;
    }

    // Invoke() isn't on the interface so cannot be accessed here
    public void Initialize(IDictionary parameters)
    {
        // Call 'super' if needed.
        _wrappedJobPlugin.Initialize(parameters);
        //concrete plugin initialization code here ...
    }

    public bool IsActive
    {
        get { return _wrappedJobPlugin.IsActive; }
        set { _wrappedJobPlugin.IsActive = value; }
    }

    public void CheckParameter()
    {
        _wrappedJobPlugin.CheckParameter();
    }
}
注释

  • 因为
    ConcreteExecutablePlugin
    不再是
    PluginBase
    的子类,如果将方法
    PluginBase.Invoke
    更改为
    protected
    ,则
    ConcreteExecutablePlugin
    将无法访问它(除了反射之类的黑客攻击)
  • 组合(née base)类
    ExecutableJobPlugin
    所需的所有“重用”方法和属性都需要在
    ConcreteExecutablePlugin
    中重新布线。虽然有点乏味,但它确实允许额外的拦截,例如日志记录等横切问题
  • ExecutableJobPlugin
    类可能不再是抽象类,因为合成工作需要一个实例
  • 理想情况下,
    ExecutableJobPlugin
    应该从外部注入(而不是
    new
    内部)
  • 通过接口进行解耦可以提高类层次结构的可测试性
  • *
    密封
    ExecutableJobPlugin
    不会阻止其他人子类化公共超类,如
    PluginBase
    JobPlugin
    。为了防止这种情况,您可以将所有基类保留在同一个程序集中,并将它们标记为
    internal
    ,或者继续在整个链中应用接口解耦/装饰器模式,而不是继承

显然,该模式可以在类层次结构的多个级别上重复,并且应该应用该模式以确保接口保持精简和集中。

基本抽象方法被声明为
public
,这将从设计上表明它在意图上是可见的?@StuartLC,实际上,我已经有了更多的继承级别,你不能在派生类型中隐藏公共方法。也许它应该被
保护
或者通过接口实现?@LasseV.Karlsen您认为使用sealed解决这个问题怎么样?您仍然无法隐藏您继承的公共方法。将类密封只会阻止声明新的子类型。我添加了一些更多信息