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

时间:2010-07-05 07:27:42

标签: c# .net interface abstract-class

我有以下代码。我需要隐藏界面的一个功能。

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的问题。

我需要每个具体的类实现IInterfaceToImplement的函数列表。此外,我需要每个具体的类能够存储IInterfaceToImplement类的类。 这是树状数据存储。存储的每个“分支”都必须执行与任何其他分支相同的操作。但除了'root'和其他'braches'之外,没有其他人必须调用这些操作。

EDIT2 我的解决方案。

感谢Matthew Abbott和Pavel Minaev。我终于意识到了我的问题 - 这是大脑。 :)

不,我在开玩笑。 :)问题是 - 我认为root和branch类属于同一个分支。现在我明白了 - 根不应该实现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 个答案:

答案 0 :(得分:2)

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

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.

你能看到这个问题吗?

答案 1 :(得分:1)

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

public abstract MyBaseClass<T> : TheVeryHeavyBaseClass<T> 
{ 
    // remove the interface the defined this
    protected abstract void AFunctionToImplement(); 

    // other code
} 

答案 2 :(得分:1)

无论何时编写接口,您都隐式声明了实现它的任何类的公共视图,因此尝试隐藏其方法根本没有意义。您可以从界面中取出AFunctionImplementation并将其保留在MyBase类中。任何MyBase类的实现仍然可以访问它。

在这种情况下,您还可以使MyBase类直接实现IOne和ITwo。

将一个带有“Implementation”一词的函数作为其名称的一部分将是一个很好的提示,可以避免将其放在接口中,因为接口通常用作将使用与实现细节隔离的手段。

答案 3 :(得分:1)

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

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

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

答案 4 :(得分:1)

public class MyRootClass : IOne, ITwo
{
    private IInterfaceToImplement internalData = new MyConcreteClass();

    public int FunctionOne() { return this.internalData.FunctionOne(); }

    public double FunctionTwo() { return this.internalData.FunctionTwo(); }
}