代码之家  ›  专栏  ›  技术社区  ›  Vasyl Boroviak

部分保护接口但没有抽象类

  •  2
  • Vasyl Boroviak  · 技术社区  · 14 年前

    我有以下代码。我需要隐藏接口的一个函数。

    interface IOne
    {
        int FunctionOne();
    }
    
    interface ITwo
    {
        double FunctionTwo();
    }
    
    interface IInterfaceToImplement : IOne, ITwo
    {
        void AFunctionToImplement();
    }
    
    public abstract MyBaseClass : TheVeryHeavyBaseClass<T, IInterfaceToImplement>, IInterfaceToImplement
    {
        public abstract void AFunctionToImplement(); // How to force this one to be protected?
    
        public virtual int FunctionOne() { return 0; }
    
        public virtual double FunctionTwo() { return 0.0; }
    }
    
    public MyConcreteClass : MyBaseClass
    {
        public override void AFunctionToImplement(); // How to force this one to be protected?
    }
    

    AFunctionToImplement() 隐藏起来。我的课程设计很差吗?关于如何保护函数不被调用有什么建议吗?

    编辑。对评论中Pavel Minaev问题的回答。

    我需要每个具体的类实现iInterfaceTomplement中的函数列表。我还需要每个具体类能够存储IInterfaceoImplement类型的类。 这是树状的数据存储。

    我的解决方案。

    谢谢马修·阿博特和帕维尔·米纳耶夫。我终于意识到了我的问题——那是大脑

    不,我在开玩笑。:)问题是-我认为根类和分支类属于同一个分支。现在我明白了-根不应该实现 IInterfaceToImplement

    public class MyRootClass : IOne, ITwo
    {
        private IInterfaceToImplement internalData = new MyConcreteClass();
    
        public int FunctionOne() { return this.internalData.FunctionOne(); }
    
        public double FunctionTwo() { return this.internalData.FunctionTwo(); }
    }
    
    5 回复  |  直到 14 年前
        1
  •  2
  •   Matthew Abbott    14 年前

    我建议使用显式接口实现:

    void IInterfaceToImplement.AFunctionToImplement();
    

    …但这不允许您在子类中公开和实现该方法,并且仍然将其隐藏。在这种情况下,您可能需要重新考虑您的类设计。

    你最好的选择是这样的:

    public interface IMyInterface
    {
        void DoWork();
    }
    
    public abstract class MyInterfaceBase : IMyInterface
    {
        /// <summary>
        /// Forced implementation.
        /// </summary>
        protected abstract void DoWork();
    
        /// <summary>
        /// Explicit implementation.
        /// </summary>
        void IMyInterface.DoWork()
        {
            // Explicit work here.
    
            this.DoWork();
        }
    }
    

    如果方法是从IMyInterface引用而不是MyInterfaceBase引用调用的,那么仍然存在让DoWork公开的问题。你根本绕不过去。如果我做了以下事情:

    MyInterface first = new MyInterface(); // Let's assume I have implemented MyInterface : MyInterfaceBase
    first.DoWork(); // Compile error, can't access method here.
    

    鉴于:

    IMyInterface second = new MyInterface();
    second.DoWork(); // No problem.
    

        2
  •  1
  •   Matthew Whited    14 年前

    只能为公共成员定义接口。如果您希望一个方法只被定义为受保护的,那么不要为它创建接口,而只是将它创建为抽象基类的受保护的抽象成员。即使您要使用显式接口,如果实例是相关接口类型的case,那么它仍然可以公开访问。

    public abstract MyBaseClass<T> : TheVeryHeavyBaseClass<T> 
    { 
        // remove the interface the defined this
        protected abstract void AFunctionToImplement(); 
    
        // other code
    } 
    
        3
  •  1
  •   Trap    14 年前

    无论何时编写接口,都是隐式声明实现它的任何类的公共视图,因此尝试隐藏其方法是毫无意义的。您可以将FunctionImplementation从接口中移除,并将其保留在MyBase类中。MyBase类的任何实现都可以访问它。

    在这种情况下,还可以让my基类直接实现IOne和ITwo。

        4
  •  1
  •   Flavius    14 年前

    也许可以在抽象类中使方法成为虚拟的,然后抛出一个异常

        /// <summary>
        /// Available only in derived classes
        /// </summary>
        public virtual void AFunctionToImplement2()
        {
            throw new ProtectedMethodException("Please do not call this method in the base class:) ");
        }
    

    我不知道这是不是一个愚蠢的解决方案,但至少你不允许用户使用这个方法,即使它是公共的。

        5
  •  1
  •   Vasyl Boroviak    14 年前
    public class MyRootClass : IOne, ITwo
    {
        private IInterfaceToImplement internalData = new MyConcreteClass();
    
        public int FunctionOne() { return this.internalData.FunctionOne(); }
    
        public double FunctionTwo() { return this.internalData.FunctionTwo(); }
    }