如何使子派生 类 无法访问成员?

How do you make members inaccessible to sub-derived classes?

假设我有这样一个基础class:

public abstract class MyBaseClass
{
  protected void MyMethod(string myVariable)
  {
    //...
  }
}

然后我在一个单独的程序集中继承这个class:

public abstract class MyDerivedClass : MyBaseClass
{
  static readonly string MyConstantString = "Hello";
  protected void MyMethod()
  {
    MyMethod(MyConstantString);
  }
}

我现在想确保从 MyDerivedClass 继承的任何其他 class 无法访问 MyBaseClass.MyMethod() 方法。 (澄清一下,我仍然希望能够不带参数调用 MyDerivedClass.MyMethod()

我尝试使用 protected internal,但没有用。

更新:我正在尝试这样做,因为我正在处理的应用程序有一堆使用基础 class 的独立程序。有 5 个不同的 "types" 程序,每个程序都执行一个特定的、独立的功能,但它们都有一些我试图抽象到这个基础 class 中的通用代码。通用代码 99% 相同,只是根据调用它的程序类型略有不同。这就是为什么我的基 class 在示例中采用字符串参数,然后在派生基 class 中消失,因为 class 知道它执行角色 x 所以它告诉它的基 class相应地。

然后我会在 MyDerivedClass 中使用组合而不是继承。所以从这个 class 派生的所有 classes 都不知道 MyBaseClass 的方法。 class MyBaseClass 我会让包可见所以不可能使用它。

abstract class MyBaseClass
{
  void MyMethod(string myVariable)
  {
    //...
  }
}

abstract class MyDerivedClass
{
   static readonly string MyConstantString = "Hello";
   private MyBaseClass baseClass;

   MyDerivedClass(MyBaseClass baseClass) 
   {
       this.baseClass = baseClass;
   }

  protected void MyMethod()
  {
    baseClass.MyMethod(MyConstantString);
  }
}

class 名称当然应该更改。

这不太可能。这可能表明您的对象设计可能有问题,但这不是 SO 的问题。

不过,您可以尝试更卑鄙的方法:

public abstract class MyBaseClass
{
  protected abstract string MyConstantString { get; }

  protected void MyMethod()
  {
    //...
  }
}

public abstract class MyDerivedClass : MyBaseClass
{
  protected override sealed string MyConstantString => "Hello";
}

或者,更典型的是,只使用构造函数传递所需的参数:

public abstract class MyBaseClass
{
  private readonly string myString;

  protected MyBaseClass(string myString)
  {
    this.myString = myString;
  }

  protected void MyMethod()
  {
    //...
  }
}

public abstract class MyDerivedClass : MyBaseClass
{
  protected MyBaseClass() : base("Hello") {}
}
MyDerivedClass 派生的

类 在任何一种情况下都无法更改参数,从继承的角度来看,第二种方法更好一些(基本上,该类型是对参数的闭包它的祖先类型)。

您无法停止通过调用此方法继承 classes - 您已经做到了 protected 因此您的意图是让继承自它的 classes 可以访问它,无论是直接还是通过另一个子class.

如果你想保留继承,你能做的最好的事情就是在子class在MyDerivedClass中调用它时抛出一个错误:

public abstract class MyBaseClass
{
    protected void MyMethod(string myVariable)
    {
        Console.WriteLine(myVariable);
    }
}

public abstract class MyDerivedClass : MyBaseClass
{
    static readonly string MyConstantString = "Hello";
    protected void MyMethod()
    {
        base.MyMethod(MyConstantString);
    }

    protected new void MyMethod(string myVariable)
    {
        throw new Exception("Not allowed");
    }
}

public class SubDerivedClass : MyDerivedClass
{
    static readonly string MyConstantString = "Hello";
    public void Foo()
    {
        MyMethod(MyConstantString);
    }
}

Foo()SubDerivedClass中调用时,它会在DerivedClass中调用MyMethod,这将抛出异常。