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

Prevent calling base class implemented interface method in the derived class C#

是否可以在基础 class 中实现一个接口并允许 calling/overriding 在第一个派生 class 级别中实现该方法,但阻止从任何进一步的派生 classes?

    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

从研究来看,我认为这可能是不可能的,因为接口必须是 public,否则使用它们没有实际价值。

在我的例子中,我需要 class Sub2 才能访问 Sub1 中的属性,但仅此而已,无法访问 class 上的方法,特别是接口实现方法。

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

    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

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

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

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

那要编译:

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

根据经验,如果您有两个 classes X 和 Y,并且只有 some 对 X 的 public 操作有效对于 Y,那么 Y 不应该派生自 X。您应该能够将派生 class 的任何实例视为基础 class(及其实现的所有接口)的实例。

在 Sub1

中使用 sealed protected override bool Test()

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

为此: