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

时间:2016-06-07 09:47:36

标签: c# abstraction access-modifiers

说我有这样的基类:

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

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

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

我现在想确保从MyDerivedClass继承的任何其他类都无权访问MyBaseClass.MyMethod()方法。 (为了澄清,我仍然希望能够在没有参数的情况下调用MyDerivedClass.MyMethod()

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

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

3 个答案:

答案 0 :(得分:2)

然后我会使用MyDerivedClass中的组合代替继承。因此,此类中的所有派生类都不知道MyBaseClass中的方法。类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);
  }
}

当然应该改变班级名称。

答案 1 :(得分:0)

这不太可能。这可能表明您的对象设计可能存在问题,但这不是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派生的类在任何一种情况下都无法更改参数,第二种方法从继承角度来看更好一些(基本上,类型是对其祖先类型的参数的闭包)。 / p>

答案 2 :(得分:0)

你不能停止继承类来调用这个方法 - 你已经使它成为protected所以你的意图是它可以被从它继承的类访问,无论是直接还是通过另一个子类。

如果你想保留继承,你可以做的最好的事情就是如果子类在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时,它会在MyMethod中调用DerivedClass,这会抛出异常。