我们可以在父 class 中定义一个方法,该方法可以在子内部调用但不能在另一个子内部调用吗

can we define a method in parent class which can be called within a child but not the other one

i 运行 陷入一个问题,我想在父 class (A) 中有一个方法 (M),然后 B 和 C 扩展 class A。在这种情况下,我希望 B 可以访问 method(M) 而不是 C 。有什么解决办法吗?

public class A
{
    ????? string M()
    {
        return "Hi there";
    }
}
public class B:A
{
}
public class C:A
{
}
B newClassB = new B();
C newClassC = new C();
Console.WriteLine(newClassB.M()); //the correct one
Console.WriteLine(newClassC.M()); //the incorrect one

in this situation i want method(M) can be accessible by B but not C . any solution?

正如我在评论中所说,你不能那样做,但你可以这样做:

class A 
{

  public virtual bool Before() { return false; }

  public void BaseMethod () 
  {         
      if(Before())
         Console.WriteLine("Called method AMethod");
  }
}

class B : A 
{    
    public override bool Before() {return true; }
}

class C : A 
{    
}

void Main()
{
    var c = new C(); 
    var b = new B(); 

    c.BaseMethod(); 
    b.BaseMethod();
}

在这种情况下,BaseMethod() 将对 C 实例执行无效。

其他一些答案似乎鼓励您违反 Liskov Substitution Principle,这是非常糟糕的做法,只会导致糟糕的代码。

你这里有一个设计问题。如果您希望 C 继承 A 那么它的行为应该与 A 完全相同,但具有添加或修改的功能。

里氏原理指出:

"Objects in a program should be replaceable with instances of their subtypes without altering the correctness of that program."

对于您想做的事情,您可能可能破坏事物。假设您有一个方法接受您的父 class A,但您将派生的 class C 传递给它。当您的方法尝试调用 C.M() 时会发生什么?

您需要做的是重新考虑您的 class 设计。如果您不应该从 C 调用 M(),那么 C 真的 A 的子类型吗?

您问题的代码非常含糊,因此我无法针对您的 class 结构提出替代解决方案,但如果您能让您的代码不那么含糊,我会进行编辑。

好的,一个有用的答案(我之前的答案不是)。

不,你不能也不应该这样做,因为其他答案和评论中已经指出了 Liskov 替换原则。

然而,在某些情况下它是合理的,事实上,NET 中的某些 类 确实实现了以下模式:

public class A
{
    public virtual bool CanCallM => true;
    public void M() {
        if (!CanCallM) throw new NotSupportedException();
        //do whatever }
}

public class B: A { }

public class C: A
{
    public override bool CanCallM => false;
}

漂亮吗?不多,但是您确实为消费者提供了一种方法,可以预先知道 是否可以调用 M,并且您确保在运行时 c.M 失败。

我个人更喜欢这种模式,而不是什么都不做,因为后者可能是代码中的错误;有人打电话给 M,期望未达到。