Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/.net/23.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 部分受保护的接口,但没有抽象类_C#_.net_Interface_Abstract Class - Fatal编程技术网

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

C# 部分受保护的接口,但没有抽象类,c#,.net,interface,abstract-class,C#,.net,Interface,Abstract Class,我有以下代码。我需要隐藏接口的一个函数 interface IOne { int FunctionOne(); } interface ITwo { double FunctionTwo(); } interface IInterfaceToImplement : IOne, ITwo { void AFunctionToImplement(); } public abstract MyBaseClass : TheVeryHeavyBaseClass<T,

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

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?
}

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

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

    // other code
} 
公共抽象MyBaseClass:TheVeryHeavyBaseClass
{ 
//删除此定义的接口
受保护的抽象无效函数实现();
//其他代码
} 

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

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();
    }
}
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.

你能看到这个问题吗?

每当你编写一个接口时,你都在隐式地声明实现它的任何类的公共视图,因此试图隐藏它的方法是毫无意义的。您可以将函数实现从接口中移除,并将其保留在MyBase类中。MyBase类的任何实现仍然可以访问它

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


如果函数的名称中有“Implementation”一词,这将是一个很好的提示,可以避免将它放在接口中,因为接口通常被用作将用法与实现细节隔离开来的一种手段。

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

    /// <summary>
    /// Available only in derived classes
    /// </summary>
    public virtual void AFunctionToImplement2()
    {
        throw new ProtectedMethodException("Please do not call this method in the base class:) ");
    }
//
///仅在派生类中可用
/// 
公共虚拟void AFunctionToImplement2()
{
抛出新的ProtectedMethodException(“请不要在基类中调用此方法:)”;
}

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

我知道所有这些。您建议在何处声明受保护的成员(请参阅问题中的代码)?很遗憾,我无法更改VeryHeavyBaseClass。我不在我的控制之下。而
veryheavybaseclass
有两个通用参数,第二个参数必须是
IInterfaceToImplement
以及MyBaseClass。谢谢你的尝试!看起来您自己的选项将明确实现该接口。然后创建它调用的第二个方法。请参阅Matthew Abbott的答案我欢迎任何设计建议!欢迎对我的课堂设计提出任何修改意见。:)问题是,为什么需要隐藏该方法?实际上,子类可以重新实现显式接口实现。他们不能做的是通过
base
调用基类实现(因为它实际上是私有的)。但也可以在显式接口实现旁边声明受保护的虚拟函数实现,并将后者委托给前者。这样,子类就可以重写它并使用
base
。这将迫使任何实现该接口的类执行此“技巧”。首先。DoWork()如果您首先对接口进行强制转换,这将起作用。你到底想达到什么目的?根据定义,接口是公共契约,将接口定义私有是没有意义的。有时将特定的实现设为半私有是有意义的,但由于可以始终获得对同一对象的接口类型引用并通过该引用调用接口方法,因此接口实现也永远不会是真正私有的。所以你想做什么?我考虑过你的建议。问题是VeryHeavyBaseClass的第二个泛型参数,MyBaseClass必须都实现同一个接口(但不是两个)。这是目前实现类的方式。:)我正试图避免这种情况。
public class MyRootClass : IOne, ITwo
{
    private IInterfaceToImplement internalData = new MyConcreteClass();

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

    public double FunctionTwo() { return this.internalData.FunctionTwo(); }
}
public class MyRootClass : IOne, ITwo
{
    private IInterfaceToImplement internalData = new MyConcreteClass();

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

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