为了提高封装性,类型或类型成员可以在声明中添加以下六个访问权限修饰符之一来限制其他类型和其他程序集对它的访问。
public
完全访问权限。这是枚举类型成员或接口成员隐含的可访问性。
internal
仅可以在程序集内访问,或供友元程序集访问。这是非嵌套类型的默认可访问性。
private
仅可以在包含类型中访问。这是类或者结构体成员的默认可访问性。
protected
仅可以在包含类型或子类中访问。
protected internal
protected 和 internal 可访问性的并集。 protected internal 修饰的成员在任意一种修饰符限定下都能够访问。
private protected (从C# 7.2开始支持)
protected 和 internal 可访问性的交集。若一个成员是 private protected 的,那么该成员只能够在定义该字段的类型中或被相同程序集中的子类型访问(它的可访问性比 protected 和 internal 都低)。
Class2 可以从本程序集外访问,而 Class1 不可以:
ClassB 的字段 x 可以被本程序集的其他类型访问,而 ClassA 的则不可以:
Subclass 中的函数可以调用 Bar 但是不能调用 Foo :
在一些高级的场景中,添加 System.Runtime.CompilerServices.InternalsVisibleTo 程序集特性就可以将 internal 成员提供给其他友元程序集访问。可以用如下方法指定友元程序集:
如果友元程序集有强名称(参见第17章),必须指定其完整的160字节公钥:
可以使用LINQ查询的方式从强命名的程序集中提取完整的公钥值(关于LINQ的介绍,请参见第8章):
LINQPad中有一个例子和本例类似,它可以选择指定程序集,而后将其完整公钥复制到剪贴板上。
类型的可访问性是它内部声明成员可访问性的上限。关于可访问性上限,最常用的示例是 internal 类型中的 public 成员。例如:
C 的(默认)可访问性是 internal ,它作为 Foo 的最高访问权限,使 Foo 成为 internal 的。而将 Foo 指定为 public 的原因一般是为了将来将 C 的权限改成 public 时方便进行重构。
当重写基类的函数时,重写函数的可访问性必须一致,例如:
(若在另外一个程序集中重写 protected internal 方法,则重写方法必须为 protected 。这是上述规则中的一个例外情况。)
编译器会阻止任何不一致的访问权限修饰符。例如,子类可以比基类的访问权限低,但不能比基类的访问权限高: