覆盖与隐藏基类方法时的C#范围差异

时间:2017-09-03 23:23:53

标签: c# scope override

我正在尝试学习C#中的继承基础知识,并且意识到我对范围和可访问性的理解存在差距。举例说明:

using System.Windows.Forms;

namespace InheritanceTests {
    class Program {
        public static void Main() {
            (new A()).Foo();      // A: 1
            (new B()).Foo();      // B: 2
            ((A)(new B())).Foo(); // B: 2 (+)
            (new C()).Foo();      // C: 3 
            ((A)(new C())).Foo(); // A: 1 (++)
        }
    }
    class A {
        private int x = 1;
        public virtual void Foo() { MessageBox.Show("A: " + this.x); }
    }
    class B : A {
        private int x = 2;
        public override void Foo() { MessageBox.Show("B: " + this.x); }
    }
    class C : A {
        private int x = 3;
        public new void Foo() { MessageBox.Show("C: " + this.x); }
    }
}

我对(+)和(++)有疑问,可能是相关的:

关于(+),为什么B实例的私有字段x即使在转换为A之后也可以访问?

关于(++),执行A的{​​{1}}方法的原因是Foo不评估为3?

1 个答案:

答案 0 :(得分:0)

  

关于(+),为什么B实例的私有字段x即使在转换为A之后也可以访问?

可以访问谁?在您的示例中,B.Foo()被调用,因为B已覆盖A.Foo()virtual)。由于被调用的方法实际上在类B中,因此该方法使用x中声明的B字段。这是该方法可以看到的唯一字段x

x中的A字段无论如何都不可见B,因为它private。但如果是(即如果它不是private),x中的字段B会隐藏它,而B的{​​{1}}实现会仍然使用Foo()课程中的x,而不是B

  

关于(++),为什么在执行A&#39的Foo方法时,this.x不能评估为3?

在此示例中,派生类A会覆盖C中的原始方法Foo()。相反,它宣布了一种全新的方法A。但是通过将对象强制转换回Foo(),编译器不再知道A中声明的方法。它可以看到的唯一方法是C被覆盖,因此A.Foo()的{​​{1}}实现被调用。

当然,该实现只能看到A中声明的Foo()字段,其中声明了方法本身。因此,您在输出中得到x而不是A