访问修饰符 (C# 编程指南)

所有类型和类型成员都具有可访问性级别。 访问级别控制程序集中的其他代码或其他程序集是否可以访问它们。 程序集是通过在单个编译中编译一个或多个 .cs 文件而创建的 .dll.exe。 可以使用以下访问修饰符在进行声明时指定类型或成员的可访问性:

  • 公共:任何程序集中的代码都可以访问此类型或成员。 包含类型的可访问性级别控制该类型的公共成员的可访问性级别。
  • 专用:只有在同一 classstruct 中声明的代码才能访问此成员。
  • 受保护:只有同一 class 或派生的 class 中的代码才能访问此类型或成员。
  • 内部:只有同一程序集中的代码才能访问此类型或成员。
  • 受保护的内部:只有同一程序集中的代码或另一个程序集的派生类中的代码才能访问此类型或成员
  • 专用受保护:只有同一程序集和同一类/派生类中的代码才能访问该类型或成员

使用 file 修饰符来应用于顶层(非嵌套)类型。 修饰 file 符限制对同一源文件中的代码的访问。 不能将 file 修饰符与任何访问修饰符结合。

类型上的 record 修饰符会导致编译器合成额外的成员。 record 修饰符不会影响 record classrecord struct 的默认可访问性。

摘要表

调用方的位置 public protected internal protected internal private protected private
在类内 ✔️️ ✔️ ✔️ ✔️ ✔️ ✔️
派生类(相同程序集) ✔️ ✔️ ✔️ ✔️ ✔️
非派生类(相同程序集) ✔️ ✔️ ✔️
派生类(不同程序集) ✔️ ✔️ ✔️
非派生类(不同程序集) ✔️

下面的示例演示如何在类型和成员上指定访问修饰符:

public class Bicycle
{
    public void Pedal() { }
}

不是所有访问修饰符都可以在所有上下文中由所有类型或成员使用。 在某些情况下,包含类型的可访问性会限制其成员的可访问性。

分部类或分部成员的多个声明必须具有相同的可访问性。 如果一个声明不包含访问修饰符,则其他声明无法声明访问修饰符。 如果分部类或分部方法的多个声明声明了不同的可访问性,编译器会生成错误。

类和结构可访问性

直接在命名空间中声明的类和结构(不嵌套在其他类或结构中)可以具有 publicinternal 访问。 如果未指定访问修饰符,则默认值为 internal。 还可以使用 file 修饰符来限制对当前源文件的访问。

可以将结构成员声明为publicinternalprivate,这些成员可以包括嵌套类和结构。 可以将类成员声明为publicprotected internalprotectedinternalprivate protectedprivate,包括嵌套类和结构体。 默认情况下,类和结构成员(包括嵌套类和结构)具有 private 访问权限。

派生类不能具有高于其基类型的可访问性。 不能声明派生自内部类 B 的公共类 A。 如果允许这样,则它将具有使 A 公开的效果,因为可从派生类访问 protected 的所有 internalA 成员。

可以通过使用 InternalsVisibleToAttribute 启用特定的其他程序集访问内部类型。 有关详细信息,请参阅友元程序集

其他类型

可以直接将命名空间中的接口声明为 publicinternal。 与类和结构一样,接口默认为 internal 访问。 接口成员默认为 public,因为接口的用途是启用其他类型以访问类或结构。 接口成员声明可以包含任何访问修饰符。 使用访问修饰符对 interface 成员进行限制,以向接口的所有实现者提供所需的通用实现。

默认情况下,在命名空间中声明的 delegate 类型具有 internal 访问权限。

有关访问修饰符的详细信息,请参阅可访问性级别页面。

成员可访问性

可以使用六种访问类型之一声明classstruct 的成员(包括嵌套类和结构)。 不能将结构成员声明为 protectedprotected internal或者 private protected 因为结构不支持继承。

通常情况下,成员的可访问性不大于包含该成员的类型的可访问性。 但是,如果 public 类中的 internal 成员实现接口方法或重写在公共基类中定义的虚拟方法,则可以从程序集外部访问它。

为字段、属性或事件的任何成员的类型必须至少与该成员本身具有相同的可访问性。 同样,任何方法、索引器或委托的返回类型和参数类型必须至少与该成员本身具有相同的可访问性。 例如,除非 public 也是 M,否则不能具有返回类 CC 方法 public。 同样,如果 protected 声明为 A,则不能具有类型 Aprivate 属性。

必须始终将用户定义的运算符声明为 public。 有关详细信息,请参阅运算符重载

若要设置 classstruct 成员的访问级别,请向成员声明添加适当的关键字,如以下示例中所示。

// public class:
public class Tricycle
{
    // protected method:
    protected void Pedal() { }

    // private field:
    private int _wheels = 3;

    // protected internal property:
    protected internal int Wheels => _wheels;
}

终结器不能具有可访问性修饰符。 enum类型的成员总是public,而且你不能应用访问修饰符。

C# 语言规范

有关详细信息,请参阅 C# 语言规范。 该语言规范是 C# 语法和用法的权威资料。

请参阅