using System;
namespace _protected
{
//----------------实例成员的受保护访问
// 当在声明了某个 protected 实例成员的类的程序文本之外访问该实例成员时,
// 以及当在包含有某个 protected internal 实例成员声明的程序的程序文本之外访问该实例成员时,
// 要求这种访问发生在该成员所属类的一个派生类的程序文本中,并引用该派生类的一个实例。
// 假定 B 是一个基类,它声明了一个受保护的实例成员 M,而 D 是从 B 派生的类。
// 在 B 的类体中,对 M 的访问可采取下列形式之一:
//
// M 形式的非限定类型名或初等表达式。 (this.M)
// F.M 形式的初等表达式(其中,F 是类 B 或是从 B 派生的类)。
// 在 D 的类体中,对 M 的访问可采取下列形式之一:
//
// M 形式的非限定类型名或初等表达式。 (this.M)
// E.M 形式的初等表达式(其中,E 是类 D 或是从 D 派生的类)。
// base.M 形式的初等表达式。
// (由于base关键字具有特殊的含义,编译器可以判断出base引用的一定是基类的派生类的实例base = (B)D)
//
// 在 D 的类体中,对 M 的访问不可采取下列形式:
//
// B.M 不能通过基类型的变量(与基类型的变量所引用的实例类型无关)引用保护成员
// 编译器无法判断B引用的是B的实例,还是B的派生类D的实例
public class A
{
protected int x;
protected void ABase()
{
Console.WriteLine(this.GetType());
}
public A()
{
}
public void F()
{
A a = new A();
B b = new B();
C c = new C();
A ab = b;
A ac = c;
x = 0;
this.x = 0;
a.x =1;
b.x = 1;
c.x =2;
ab.x = 3;
ac.x = 3;
}
}
// 在 A 中可以通过 A 和 B 的实例访问 x,这是因为在两种情况下访问都通过 A 的实例或从 A 派生的类发生。
// 但是在 B 中,由于 A 不从 B 派生,所以不可能通过 A 的实例访问 x。
public class B: A
{
int y;
public new void F()
{
A a = new A();
B b = new B();
C c = new C();
A ab = b;
A ac = c;
x = 0;
this.x = 0;
b.x = 1;
c.x =2;
//编译器无法判断a、ab、ac引用的是A的实例,还是A的派生类B、C的实例
// a.x =1;
// ab.x = 3;
// ac.x = 3;
//由于base关键字具有特殊的含义,编译器可以判断出base引用的一定是基类的派生类的实例
base.x = 1;
base.ABase();
// Console.WriteLine(base.GetType());
// Console.WriteLine(this.GetType());
}
}
public class C: B
{
int z;
public new void F()
{
A a = new A();
B b = new B();
C c = new C();
A ab = b;
A ac = c;
x = 0;
this.x = 0;
c.x =2;
// a.x =1;
// b.x = 1;
// ab.x = 3;
// ac.x = 3;
base.x = 2;
base.ABase();
}
}
/// <summary>
/// Class1 的摘要说明。
/// </summary>
class class1
{
/// <summary>
/// 应用程序的主入口点。
/// </summary>
[STAThread]
static void Main(string[] args)
{
A a = new A();
B b = new B();
C c = new C();
a.F();
b.F();
c.F();
}
}
}