已声明可访问性(MSDN)

成员的“已声明可访问性”可以是下列之一:

  • Public,选择它的方法是在成员声明中包括 public 修饰符。public 的直观含义是“访问不受限制”。
  • Protected,选择它的方法是在成员声明中包括 protected 修饰符。protected 的直观含义是“访问范围限定于它所属的类或从该类派生的类型”。
  • Internal,选择它的方法是在成员声明中包括 internal 修饰符。internal 的直观含义是“访问范围限定于此程序”。
  • Protected internal(意为受保护或内部的),选择它的方法是在成员声明中包括 protectedinternal 修饰符。protected internal 的直观含义是“访问范围限定于此程序或那些由它所属的类派生的类型”。
  • Private,选择它的方法是在成员声明中包括 private 修饰符。private 的直观含义是“访问范围限定于它所属的类型”。

声明一个成员时所能选择的已声明可访问性的类型,依赖于该成员声明出现处的上下文。此外,当成员声明不包含任何访问修饰符时,声明发生处的上下文会为该成员选择一个默认的已声明可访问性。

  • 命名空间隐式地具有 public 已声明可访问性。在命名空间声明中不允许使用访问修饰符。
  • 编译单元或命名空间中声明的类型可以具有 publicinternal 已声明可访问性,默认的已声明可访问性为 internal
  • 类成员可具有五种已声明可访问性中的任何一种,默认为 private 已声明可访问性。(请注意,声明为类成员的类型可具有五种已声明可访问性中的任何一种,而声明为命名空间成员的类型只能具有 publicinternal 已声明可访问性。)
  • 结构成员可以具有 publicinternalprivate 已声明可访问性并默认为 private 已声明可访问性,这是因为结构是隐式地密封的。结构的成员若是在此结构中声明的(也就是说,不是由该结构从它的基类中继承的)不能具有 protectedprotected internal 已声明可访问性。(请注意,声明为结构成员的类型可具有 publicinternalprivate 已声明可访问性,而声明为命名空间成员的类型只能具有 publicinternal 已声明可访问性。)
  • 接口成员隐式地具有 public 已声明可访问性。在接口成员声明中不允许使用访问修饰符。
  • 枚举成员隐式地具有 public 已声明可访问性。在枚举成员声明中不允许使用访问修饰符。

一个成员的可访问域由(可能是不连续的)程序文本节组成,从那里可以访问该成员。出于定义成员可访问域的目的,如果成员不是在某个类型内声明的,就称该成员是顶级的;如果成员是在其他类型内声明的,就称该成员是嵌套的。此外,程序的程序文本定义为包含在该程序的所有源文件中的全部程序文本,而类型的程序文本定义为包含在该类型(可能还包括嵌套在该类型内的类型)的“类体”、“结构体”、“接口体”或“枚举体”中的开始和结束(“{”和“}”)标记之间的全部程序文本。

预定义类型(如 objectintdouble)的可访问域是无限制的。

在程序 P 中声明的顶级类型 T 的可访问域如下定义:

  • 如果 T 的已声明可访问性为 public,则 T 的可访问域是 P 的以及引用 P 的任何程序的程序文本。
  • 如果 T 的已声明可访问性为 internal,则 T 的可访问域是 P 的程序文本。

从这些定义可以推断出:顶级类型的可访问域始终至少是声明了该类型的程序的程序文本。

在程序 P 内的类型 T 中声明的嵌套成员 M 的可访问域如下定义(注意 M 本身可能就是一个类型):

  • 如果 M 的已声明可访问性为 public,则 M 的可访问域是 T 的可访问域。
  • 如果 M 的已声明可访问性是 protected internal,设 D 表示 P 的程序文本和从 T 派生的任何类型(在 P 的外部声明)的程序文本的并集。M 的可访问域是 TD 的可访问域的交集。
  • 如果 M 的已声明可访问性是 protected,则设 D 表示 T 的程序文本和从 T 派生的任何类型的程序文本的并集。M 的可访问域是 TD 的可访问域的交集。
  • 如果 M 的已声明可访问性为 internal,则 M 的可访问域是 T 的可访问域与 P 的程序文本的交集。
  • 如果 M 的已声明可访问性为 private,则 M 的可访问域是 T 的程序文本。

从这些定义可以看出:嵌套成员的可访问域总是至少为声明该成员的类型的程序文本。还可以看出:成员的可访问域包含的范围决不会比声明该成员的类型的可访问域更广。

用直观的话来讲,当访问类型或成员 M 时,按下列步骤进行计算以确保允许进行访问:

  • 首先,如果 M 是在某个类型(相对于编译单元或命名空间)内声明的,则当该类型不可访问时将会发生编译时错误。
  • 然后,如果 Mpublic,则允许进行访问。
  • 否则,如果 Mprotected internal,则当访问发生在声明了 M 的程序中,或发生在从声明 M 的类派生的类中并通过派生类类型(第 3.5.3 节)进行访问时,允许进行访问。
  • 否则,如果 Mprotected,则当访问发生在声明了 M 的类中,或发生在从声明 M 的类派生的类中并通过派生类类型(第 3.5.3 节)进行访问时,允许进行访问。
  • 否则,如果 Minternal,则当访问发生在声明了 M 的程序中时允许进行访问。
  • 否则,如果 Mprivate,则当访问发生在声明了 M 的类型中时允许进行访问。
  • 否则,类型或成员不可访问,并发生编译时错误。

在下面的示例中,

public class A
{
   public static int X;
   internal static int Y;
   private static int Z;
}
internal class B
{
   public static int X;
   internal static int Y;
   private static int Z;
   public class C
   {
      public static int X;
      internal static int Y;
      private static int Z;
   }
   private class D
   {
      public static int X;
      internal static int Y;
      private static int Z;
   }
}

类和成员具有下列可访问域:

  • AA.X 的可访问域无限制。
  • A.YBB.XB.YB.CB.C.XB.C.Y 的可访问域是包含程序的程序文本。
  • A.Z 的可访问域是 A 的程序文本。
  • B.ZB.D 的可访问域是 B 的程序文本,包括 B.CB.D 的程序文本。
  • B.D.XB.D.Y 的可访问域是 B 的程序文本,包括 B.CB.D 的程序文本。
  • B.D.Z 的可访问域是 B.D 的程序文本。

如示例所示,成员的可访问域决不会大于包含它的类型的可访问域。例如,即使所有的 X 成员都具有公共级的已声明可访问性,但除了 A.X 外,所有其他成员的可访问域都受包含类型的约束。

第 3.4 节中所描述的那样,基类的所有成员(实例构造函数、析构函数和静态构造函数除外)都由派生类型继承。这甚至包括基类的私有成员。但是,私有成员的可访问域只包括声明该成员的类型的程序文本。在下面的示例中,

class A
{
   int x;
   static void F(B b) {
      b.x = 1;      // Ok
   }
}
class B: A
{
   static void F(B b) {
      b.x = 1;      // Error, x not accessible
   }
}

B 继承类 A 的私有成员 x。因为该成员是私有的,所以只能在 A 的“类体”中对它进行访问。因此,对 b.x 的访问在 A.F 方法中取得了成功,在 B.F 方法中却失败了。

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值