C# 为什么可以';当对象是子类类型时,我是否从超类调用子类中的公共方法?

C# 为什么可以';当对象是子类类型时,我是否从超类调用子类中的公共方法?,c#,inheritance,C#,Inheritance,我有一个类B,它是类a的子类。我创建了一个类型为B的对象并对其调用OnlyA(),但在OnlyA()内部,对OnlyB()的调用会导致编译器错误 根据我的理解,OnlyB()与此相同。OnlyB()调用的方法应从对象的类(B)中选择,而不是从执行代码的当前类(A)中选择。这就是为什么对Both()的调用调用的是B中的方法,而不是A中的方法。那么为什么它只搜索A中的B(),而不是B中的?我怎么知道调用的方法是从对象的类还是当前类中选择的 class Program { static voi

我有一个类B,它是类a的子类。我创建了一个类型为B的对象并对其调用OnlyA(),但在OnlyA()内部,对OnlyB()的调用会导致编译器错误

根据我的理解,
OnlyB()
与此相同。OnlyB()调用的方法应从对象的类(B)中选择,而不是从执行代码的当前类(A)中选择。这就是为什么对Both()的调用调用的是B中的方法,而不是A中的方法。那么为什么它只搜索A中的B(),而不是B中的?我怎么知道调用的方法是从对象的类还是当前类中选择的

class Program
{
    static void Main(string[] args)
    {
        B bRefB = new B();

        bRefB.OnlyA();
    }
}

class A
{
    public void OnlyA()
    {
        Console.WriteLine("In A - OnlyA()");
        OnlyB(); // compiler error
        Both();  // calls the method in B
    }

    public virtual void Both()
    {
        Console.WriteLine("In A - Both()");
    }
}

class B : A
{
    public void OnlyB()
    {
        Console.WriteLine("In B - OnlyB()");
    }

    public override void Both()
    {
        Console.WriteLine("In B - Both()");
    }
}

您完全正确地认为
OnlyB
this.OnlyB
相同。这就是问题所在<代码>此属于
A类型
。它不知道
B
甚至存在(也不应该存在)

超类根本不知道(也不应该知道)它们有派生类,更不用说其中包含什么方法了。这不是一个“搜索”的问题;当您的
C
没有定义
OnlyB
时会发生什么?将调用什么方法


另一方面,子类总是超类的子类;因此,它们可以安全地调用基类方法。

您绝对正确地认为
OnlyB
this.OnlyB
相同。这就是问题所在<代码>此属于
A类型
。它不知道
B
甚至存在(也不应该存在)

超类根本不知道(也不应该知道)它们有派生类,更不用说其中包含什么方法了。这不是一个“搜索”的问题;当您的
C
没有定义
OnlyB
时会发生什么?将调用什么方法

另一方面,子类总是超类的子类;因此,它们可以安全地调用基类方法。

Bradely的文章介绍了代码不起作用的原因(
类型为
A
)。以下是将需求编写为代码的正确方法

您希望根据对象的运行时类型调用方法。由于
的编译时是当前对象的类型,所以在调用之前,您需要以某种方式将其强制转换为派生类型。可能的选择:

  • just cast-静态检查B是否只有B
    OnlyB
    ,运行时强制转换异常:

    ((B)this).OnlyB(); 
    
  • 使用
    dynamic
    -无静态类型检查,如果实际类没有
    OnlyB
    方法,则在运行时异常,无论它是否来自B、C

    dynamic b = this;
    b.OnlyB(); 
    
  • 手动反射调用(与
    动态
    相同)

  • 泛型-参见
布雷德利的文章介绍了代码不起作用的原因(
属于
A
)。以下是将需求编写为代码的正确方法

您希望根据对象的运行时类型调用方法。由于
的编译时是当前对象的类型,所以在调用之前,您需要以某种方式将其强制转换为派生类型。可能的选择:

  • just cast-静态检查B是否只有B
    OnlyB
    ,运行时强制转换异常:

    ((B)this).OnlyB(); 
    
  • 使用
    dynamic
    -无静态类型检查,如果实际类没有
    OnlyB
    方法,则在运行时异常,无论它是否来自B、C

    dynamic b = this;
    b.OnlyB(); 
    
  • 手动反射调用(与
    动态
    相同)

  • 泛型-参见

想象一下,如果您没有遇到编译器错误。静态输入有什么好处?您可以从中调用任何内容,直到运行时才得到错误。想象一下,如果您没有得到编译器错误。静态输入有什么好处?您可以从调用中调用任何内容,直到运行时才得到错误。因此,超类调用子类中的方法(无需使用某些高级技术)的唯一方法是调用在子类中重写的方法?换句话说,超类不能访问任何子类方法,除非它们重写超类中的方法?@000 Correct;这是做这件事的唯一方法。请注意,您可以使用
abstract
而不是
virtual
来表示基类不定义行为并强制派生类实现它。这当然意味着基类不再是可构造的,因此超类调用子类中的方法(不使用某些高级技术)的唯一方法是调用在子类中重写的方法?换句话说,超类不能访问任何子类方法,除非它们重写超类中的方法?@000 Correct;这是做这件事的唯一方法。请注意,您可以使用
abstract
而不是
virtual
来表示基类不定义行为并强制派生类实现它。这当然意味着基类不再是可构造的