防止在派生类C#中调用基类实现的接口方法

时间:2015-03-19 10:43:26

标签: c# class interface base derived

是否可以在基类中实现接口并允许在第一个派生类级别中调用/覆盖已实现的方法,但是阻止从任何其他派生类调用它?

    public interface IInterfaceSample
    {
        bool Test();
    }

    public class Base: IInterfaceSample
    {
        public virtual bool Test()
        {
             return True;
        }
    }

    public class Sub1: Base
    {
        //I need to be able to override the Test method here
        public override bool Test()
        {
             return True;
        }
    }

    //Under a separate project:
    public class Sub2: Sub1
    {
       //I need to prevent overriding the interface implementation in this class
    }

现在我需要的是:

    var b = new Base();
    b.Test();//This should work

    var s1 = new Sub1();
    s1.Test();//I need this to work too

    var s2 = new Sub2();
    s2.Test();//I need to prevent doing this

从研究到目前为止,我认为这可能是不可能的,因为接口必须是公开的,否则使用它们没有实际价值。

在我的情况下,我需要类Sub2才能访问Sub1中的属性,但只能访问该类的属性,并且无法访问该类的方法,特别是接口实现方法。

我能够做到这一点的唯一方法是根本不使用接口并按照这样做:

    public class Base
    {
        internal virtual bool Test()
        {
             return True;
        }
    }

    public class Sub1: Base
    {
        //I am able to override the Test method here
        internal override bool Test()
        {
             return True;
        }
    }

    //Under a separate project:
    public class Sub2: Sub1
    {
       //Nothing to override here which is what i need
    }

    var b = new Base();
    b.Test();//This works

    var s1 = new Sub1();
    s1.Test();//This works too

    var s2 = new Sub2();
    s2.Test();//This is prevented

但是我想知道这是否仍然可以通过接口实现,我们非常感谢任何帮助。

3 个答案:

答案 0 :(得分:3)

不,这是不可能的 - 它会破坏多态性的全部意义。特别是,假设您没有使用var,但明确使用了类型:

Sub1 s2 = new Sub2();
s2.Test();

必须编译:

  • 第一行必须编译,因为Sub2派生自Sub1
  • 第二行必须编译,因为您需要编译s1.Test(),其中编译时类型s1也是Sub1

根据经验,如果你有两个类X和Y,并且只有 X上的公共操作的某些对Y有效,那么Y不应该从X派生。你应该能够将派生类的任何实例视为基类的实例(以及它实现的所有接口)。

答案 1 :(得分:1)

您希望Test方法仅在Sub1中可用,但仍与Sub2共享相同的属性。这可以通过改变继承链来实现:
enter image description here
对此:
enter image description here

答案 2 :(得分:-1)

在Sub1中使用sealed protected override bool Test()